this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Load BTree.FreeList entries

garrison eb98c2a4 d6cd387d

+56 -2
+54 -2
lib/btree/free_list.ex
··· 32 32 @spec load(BTree.t) :: :ok 33 33 def load(%BTree{} = btree) do 34 34 %{ 35 + store: store, 35 36 free_list: free_list, 37 + 38 + free_list_tail_address: {tail_index, tail_checksum}, 36 39 free_list_max_index: free_list_max_index, 40 + 41 + opts: %{ 42 + page_size: opt_page_size, 43 + }, 37 44 } = btree 38 45 46 + # Load max_index 39 47 :ets.insert(free_list, {:max_index, free_list_max_index}) 48 + 49 + # Load FreeList entries from the linked list of pages 50 + free_list_page_indexes = do_load_page(store, free_list, opt_page_size, tail_index, tail_checksum, []) 51 + 52 + # Free the pages used to store the list itself 53 + # (they will be pending until the next commit so they won't be overwritten during this cycle) 54 + Enum.each(free_list_page_indexes, fn index -> 55 + free_page(free_list, index) 56 + end) 57 + 40 58 :ok 41 59 end 42 60 61 + defp do_load_page(_store, _free_list_tail_address, _opt_page_size, 0 = _index, _checksum, indexes_acc) do 62 + indexes_acc 63 + end 64 + 65 + defp do_load_page(store, free_list, opt_page_size, index, checksum, indexes_acc) do 66 + page_data = Store.read_page(store, index, checksum) 67 + 68 + << 69 + _::binary-size(opt_page_size - c_free_list_page_trailer_size()), 70 + entries_size::integer-64, 71 + prev_index::integer-64, 72 + prev_checksum::binary-16, 73 + >> = page_data 74 + 75 + << 76 + entries_data::binary-size(entries_size), 77 + _::binary, 78 + >> = page_data 79 + 80 + :ok = do_load_entries(entries_data, free_list) 81 + 82 + indexes_acc = [index | indexes_acc] 83 + do_load_page(store, free_list, opt_page_size, prev_index, prev_checksum, indexes_acc) 84 + end 85 + 86 + defp do_load_entries("", _free_list), do: :ok 87 + # See constant: c_free_list_entry_size() 88 + defp do_load_entries(<<index::integer-64, entries_rest::binary>>, free_list) do 89 + :ets.insert(free_list, {[:free | index], nil}) 90 + do_load_entries(entries_rest, free_list) 91 + end 92 + 43 93 @spec flush(BTree.t) :: %{free_list_tail_address: {non_neg_integer, binary}, free_list_max_index: non_neg_integer} 44 94 def flush(%BTree{} = btree) do 45 95 %{ ··· 68 118 end 69 119 70 120 defp do_flush(store, free_list, opt_page_size, subspace, page_acc, last_address, last_key) do 71 - entries_size_max = opt_page_size - c_address_bytes() 121 + entries_size_max = opt_page_size - c_free_list_page_trailer_size() 72 122 73 123 case :ets.next(free_list, last_key) do 74 124 [^subspace | index] = key -> ··· 100 150 defp write_free_list_page(store, free_list, opt_page_size, page_data, last_address) do 101 151 {last_index, last_checksum} = last_address 102 152 103 - pad_bytes = opt_page_size - byte_size(page_data) - c_address_bytes() 153 + entries_size = byte_size(page_data) 154 + pad_bytes = opt_page_size - entries_size - c_free_list_page_trailer_size() 104 155 assert pad_bytes >= 0 105 156 106 157 page_data = << 107 158 page_data::binary, 108 159 0::integer-unit(8)-size(pad_bytes), 160 + entries_size::integer-64, 109 161 last_index::integer-64, 110 162 last_checksum::binary-16, 111 163 >>
+2
lib/btree/utils.ex
··· 10 10 11 11 # index 12 12 defmacro c_free_list_entry_size, do: 8 13 + # entries_size + prev_index + prev_checksum 14 + defmacro c_free_list_page_trailer_size, do: 8 + 8 + 16 13 15 14 16 # pair_count + type_byte 15 17 defmacro c_page_trailer_bytes, do: 2 + 1