summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/db/struct/db_item_ids_manager.erl')
-rw-r--r--src/db/struct/db_item_ids_manager.erl207
1 files changed, 0 insertions, 207 deletions
diff --git a/src/db/struct/db_item_ids_manager.erl b/src/db/struct/db_item_ids_manager.erl
deleted file mode 100644
index e2af8a6..0000000
--- a/src/db/struct/db_item_ids_manager.erl
+++ /dev/null
@@ -1,207 +0,0 @@
--module(db_item_ids_manager).
--behavior(gen_server).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--record
-(
- entry,
- {
- last_id :: binary(),
- freed_ids :: list(binary())
- }
-).
-
--type entry() :: #entry{}.
-
-%% FIXME: IDs should be generated in a decentralized fashion.
-%% TODO: How to handle IDs management with the redundancy DBs?
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%% 'gen_server' Exports
--export
-(
- [
- init/1,
- handle_cast/2,
- handle_call/3, %% No reply will ever be given.
- terminate/2,
- code_change/3,
- format_status/2,
- handle_info/2
- ]
-).
-
-%%%% Actual Interface
--export
-(
- [
- allocate/1,
- free/2,
- start/0
- ]
-).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec next_char (integer()) -> integer().
-next_char ($9) -> $a;
-next_char ($z) -> $A;
-next_char ($Z) -> $0;
-next_char (C) -> (C + 1).
-
--spec next_id_internal
- (
- list(integer()),
- boolean(),
- list(integer())
- )
- -> list(integer()).
-next_id_internal ([], true, Result) -> [$0|Result];
-next_id_internal ([], false, Result) -> Result;
-next_id_internal ([$Z|Next], true, Result) ->
- next_id_internal(Next, true, [$0|Result]);
-next_id_internal ([Char|Next], true, Result) ->
- next_id_internal(Next, false, [next_char(Char)|Result]);
-next_id_internal ([Char|Next], false, Result) ->
- next_id_internal(Next, false, [Char|Result]).
-
--spec next_id (binary()) -> binary().
-next_id (ID) ->
- list_to_binary
- (
- next_id_internal
- (
- lists:reverse(binary:bin_to_list(ID)),
- true,
- []
- )
- ).
-
--spec new_entry () -> entry().
-new_entry () ->
- #entry
- {
- last_id = <<"">>,
- freed_ids = []
- }.
-
--spec allocate_id_in_entry (entry()) -> {entry(), binary()}.
-allocate_id_in_entry (Entry) ->
- case Entry#entry.freed_ids of
- [] ->
- NewID = next_id(Entry#entry.last_id),
- {
- Entry#entry{ last_id = NewID },
- NewID
- };
-
- [OldID|OtherOldIDs] ->
- {
- Entry#entry{ freed_ids = OtherOldIDs },
- OldID
- }
- end.
-
--spec allocate_id
- (
- atom(),
- dict:dict(atom(), entry())
- )
- -> {dict:dict(atom(), entry()), binary()}.
-allocate_id (DB, State) ->
- S0Entry =
- case dict:find(DB, State) of
- {ok, Value} -> Value;
- error -> new_entry()
- end,
-
- {S1Entry, NewID} = allocate_id_in_entry(S0Entry),
-
- S0State = dict:store(DB, S1Entry, State),
-
- {S0State, NewID}.
-
--spec free_id
- (
- binary(),
- atom(),
- dict:dict(atom(), entry())
- )
- -> dict:dict(atom(), entry()).
-free_id (ID, DB, State) ->
- Entry =
- case dict:find(DB, State) of
- {ok, Value} -> Value;
- error -> new_entry()
- end,
-
- EntryFreedIDs = Entry#entry.freed_ids,
-
- case lists:member(ID, EntryFreedIDs) of
- true -> State;
- false ->
- Result =
- dict:store
- (
- DB,
- Entry#entry{ freed_ids = [ID|EntryFreedIDs] },
- State
- ),
-
- Result
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%% 'gen_server' functions
-init (_) -> {ok, dict:new()}.
-
-handle_call ({allocate, DB}, _, State) ->
- {NewState, NewID} = allocate_id(DB, State),
- {reply, {allocated_id, NewID}, NewState};
-handle_call ({free, ID, DB}, _, State) ->
- {noreply, free_id(ID, DB, State)}.
-
-handle_cast ({allocate, _DB}, State) ->
- {noreply, State};
-handle_cast ({free, ID, DB}, State) ->
- {noreply, free_id(ID, DB, State)}.
-
-terminate (_, _) -> ok.
-
-code_change (_, State, _) ->
- {ok, State}.
-
-format_status (_, [_, State]) ->
- [{data, [{"State", State}]}].
-
-handle_info(_, State) ->
- {noreply, State}.
-
-%%%% Interface Functions
--spec allocate (atom()) -> binary().
-allocate (DB) ->
- {allocated_id, Result} =
- gen_server:call({global, db_item_ids_manager}, {allocate, DB}),
-
- io:format("~n[DB: ~p] Item ID ~p allocated.~n", [DB, Result]),
-
- Result.
-
--spec free (binary(), atom()) -> 'ok'.
-free (ID, DB) ->
- gen_server:cast({global, db_item_ids_manager}, {free, ID, DB}),
-
- ok.
-
--spec start () -> 'ok'.
-start () ->
- {ok, _} = gen_server:start({global, db_item_ids_manager}, ?MODULE, none, []),
-
- ok.