emqx_sequence.erl 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_sequence).
  17. -export([ create/1
  18. , nextval/2
  19. , currval/2
  20. , reclaim/2
  21. , delete/1
  22. ]).
  23. -export_type([seqid/0]).
  24. -type(key() :: term()).
  25. -type(name() :: atom()).
  26. -type(seqid() :: non_neg_integer()).
  27. %%--------------------------------------------------------------------
  28. %% APIs
  29. %%--------------------------------------------------------------------
  30. %% @doc Create a sequence.
  31. -spec(create(name()) -> ok).
  32. create(Name) ->
  33. emqx_tables:new(Name, [public, set, {write_concurrency, true}]).
  34. %% @doc Next value of the sequence.
  35. -spec(nextval(name(), key()) -> seqid()).
  36. nextval(Name, Key) ->
  37. ets:update_counter(Name, Key, {2, 1}, {Key, 0}).
  38. %% @doc Current value of the sequence.
  39. -spec(currval(name(), key()) -> seqid()).
  40. currval(Name, Key) ->
  41. try ets:lookup_element(Name, Key, 2)
  42. catch
  43. error:badarg -> 0
  44. end.
  45. %% @doc Reclaim a sequence id.
  46. -spec(reclaim(name(), key()) -> seqid()).
  47. reclaim(Name, Key) ->
  48. try ets:update_counter(Name, Key, {2, -1, 0, 0}) of
  49. 0 -> ets:delete_object(Name, {Key, 0}), 0;
  50. I -> I
  51. catch
  52. error:badarg -> 0
  53. end.
  54. %% @doc Delete the sequence.
  55. -spec(delete(name()) -> boolean()).
  56. delete(Name) ->
  57. case ets:info(Name, name) of
  58. Name -> ets:delete(Name);
  59. undefined -> false
  60. end.