this repo has no description
2
fork

Configure Feed

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

Collect writes without decoding

garrison 62af9005 1347ef11

+87 -8
+87 -8
lib/btree/writer.ex
··· 67 67 end 68 68 69 69 defp do_flush(%BTree{} = btree, page_index, page_checksum, page_sk, page_ek) do 70 - {page_type, pairs} = 71 - BTree.read_page(btree.page_store, page_index, page_checksum) 72 - |> Page.decode_page() 70 + %{ 71 + page_store: page_store, 72 + opts: %{ 73 + page_size: opt_page_size, 74 + }, 75 + } = btree 76 + 77 + page_data = BTree.read_page(page_store, page_index, page_checksum) 78 + prefix_size = opt_page_size - c_page_trailer_bytes() 79 + # See constant: c_page_trailer_bytes() 80 + << 81 + _::binary-size(prefix_size), 82 + _count::integer-16, 83 + type_byte::integer-8, 84 + >> = page_data 85 + 86 + case type_byte do 87 + 0x00 -> flush_inner(btree, page_data, page_sk, page_ek) 88 + 0x01 -> do_flush_leaf(btree, page_data, page_sk, page_ek) 89 + end 90 + end 91 + 92 + defp flush_inner(%BTree{} = btree, page_data, page_sk, page_ek) do 93 + %{ 94 + write_buffer: write_buffer, 95 + opts: %{ 96 + page_size: opt_page_size, 97 + } 98 + } = btree 99 + 100 + prefix_size = opt_page_size - c_page_trailer_bytes() 101 + # See constant: c_page_trailer_bytes() 102 + << 103 + _::binary-size(prefix_size), 104 + pointer_count::integer-16, 105 + type_byte::integer-8, 106 + >> = page_data 107 + assert type_byte == 0x00 108 + 109 + key_count = pointer_count - 1 110 + slots_start = opt_page_size - (key_count * c_page_slot_entry_bytes()) 111 + pointers_start = slots_start - (pointer_count * c_inner_pointer_bytes()) 112 + 113 + writes = collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, [], page_sk, 0) 114 + end 115 + 116 + defp collect_inner_writes(_btree, _write_buffer, _page_data, _page_ek, _slots_start, _pointers_start, _key_count, pointer_count, writes_acc, _start_key, i) 117 + when i == (pointer_count - 1) do 118 + Enum.reverse(writes_acc) 119 + end 120 + 121 + defp collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, writes_acc, start_key, i) do 122 + assert i < pointer_count 123 + end_key = inner_end_key(page_data, page_ek, slots_start, key_count, i) 124 + 125 + case :ets.first(write_buffer) do 126 + key when is_binary(key) and key < end_key -> 127 + <<_::binary-size(pointers_start + (i * c_inner_pointer_bytes())), index::integer-64, checksum::binary-16, _::binary>> = page_data 128 + addresses = do_flush(btree, index, checksum, start_key, end_key) 73 129 74 - pairs = 75 - case page_type do 76 - :inner -> fill_inner(btree, pairs, page_sk, page_ek, []) 77 - :leaf -> fill_leaf(btree.write_buffer, page_ek, pairs) 78 - end 130 + writes_acc = [{i, addresses} | writes_acc] 131 + start_key = end_key 132 + i = i + 1 133 + collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, writes_acc, start_key, i) 134 + 135 + _ -> 136 + start_key = end_key 137 + i = i + 1 138 + collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, writes_acc, start_key, i) 139 + end 140 + end 141 + 142 + defp inner_end_key(page_data, page_ek, slots_start, key_count, i) do 143 + case i < key_count do 144 + true -> 145 + <<_::binary-size(slots_start + (i * c_page_slot_entry_bytes())), key_offset::integer-16, _::binary>> = page_data 146 + <<_::binary-size(key_offset), key_size::integer-16, key::binary-size(key_size), _::binary>> = page_data 147 + key 148 + false -> page_ek 149 + end 150 + end 151 + 152 + defp do_flush_leaf(btree, page_data, page_sk, page_ek) do 153 + {page_type, pairs} = Page.decode_page(page_data) 154 + assert page_type == :leaf 155 + 156 + pairs = fill_leaf(btree.write_buffer, page_ek, pairs) 79 157 80 158 new_encoded_pages = Page.encode_page_from_pairs(page_type, btree.opts.page_size, pairs, page_ek) 81 159 assert elem(List.last(new_encoded_pages), 0) == page_ek ··· 159 237 slots_data = encode_slots(offsets, "") 160 238 type_byte = 0x00 161 239 240 + # See constant: c_page_trailer_bytes() 162 241 page = << 163 242 keys_data::binary, 164 243 0::integer-unit(8)-size(pad_bytes),