/src/msg_store_bitcask_index.erl

https://github.com/videlalvaro/msg_store_bitcask_index · Erlang · 105 lines · 86 code · 18 blank · 1 comment · 1 complexity · c61b811e3db5d1a102476230f602fbcc MD5 · raw file

  1. -module(msg_store_bitcask_index).
  2. -behaviour(rabbit_msg_store_index).
  3. -rabbit_boot_step({msg_store_bitcask_index,
  4. [{description, "Bitcask Index for rabbit_msg_store"},
  5. {mfa, {application, set_env,
  6. [rabbit, msg_store_index_module, ?MODULE]}},
  7. {enables, recovery}]}).
  8. -export([new/1, recover/1,
  9. lookup/2, insert/2, update/2, update_fields/3, delete/2,
  10. delete_object/2, delete_by_file/2, terminate/1]).
  11. -include_lib("rabbit_common/include/rabbit_msg_store.hrl").
  12. -define(BITCASK_DIR, "bitcask_data").
  13. new(Dir) ->
  14. Path = get_path(Dir),
  15. {ok, Ref} = init(Path),
  16. Ref.
  17. recover(Dir) ->
  18. Path = get_path(Dir),
  19. {ok, Ref} = init(Path),
  20. {ok, Ref}.
  21. get_path(Dir) ->
  22. filename:join(Dir, ?BITCASK_DIR).
  23. init(Dir) ->
  24. case bitcask:open(Dir, [read_write]) of
  25. {error, Error}
  26. -> {error, Error};
  27. Ref
  28. -> {ok, Ref}
  29. end.
  30. %% Key is MsgId which is binary already
  31. lookup(Key, Bitcask) ->
  32. case bitcask:get(Bitcask, Key) of
  33. {ok, Value} -> #msg_location{} = binary_to_term(Value);
  34. _ -> not_found
  35. end.
  36. insert(Obj = #msg_location{ msg_id = MsgId }, Bitcask) ->
  37. ok = bitcask:put(Bitcask, MsgId, term_to_binary(Obj)),
  38. ok.
  39. update(Obj = #msg_location{ msg_id = MsgId }, Bitcask) ->
  40. ok = bitcask:put(Bitcask, MsgId, term_to_binary(Obj)),
  41. ok.
  42. update_fun({Position, NewValue}, ObjAcc) ->
  43. setelement(Position, ObjAcc, NewValue).
  44. update_fields(Key, Updates, Bitcask) ->
  45. case bitcask:get(Bitcask, Key) of
  46. {ok, Value} ->
  47. Obj = #msg_location{} = binary_to_term(Value),
  48. NewObj =
  49. case is_list(Updates) of
  50. true -> lists:foldl(fun update_fun/2, Obj, Updates);
  51. false -> update_fun(Updates, Obj)
  52. end,
  53. ok = bitcask:put(Bitcask, Key, term_to_binary(NewObj)),
  54. ok;
  55. _ -> not_found
  56. end,
  57. ok.
  58. delete(Key, Bitcask) ->
  59. ok = bitcask:delete(Bitcask, Key),
  60. ok.
  61. delete_object(Obj = #msg_location{ msg_id = MsgId }, Bitcask) ->
  62. case bitcask:get(Bitcask, MsgId) of
  63. {ok, Value} ->
  64. case Obj =:= binary_to_term(Value) of
  65. true ->
  66. ok = bitcask:delete(Bitcask, MsgId),
  67. ok;
  68. _ ->
  69. not_found
  70. end;
  71. _ -> not_found
  72. end.
  73. delete_by_file(File, Bitcask) ->
  74. ok = bitcask:fold(Bitcask,
  75. fun(Key, Obj, Acc) ->
  76. case (binary_to_term(Obj))#msg_location.file of
  77. File ->
  78. bitcask:delete(Bitcask, Key),
  79. Acc;
  80. _ ->
  81. Acc
  82. end
  83. end, ok),
  84. ok.
  85. terminate(Bitcask) ->
  86. ok = bitcask:close(Bitcask),
  87. ok.