this repo has no description
2
fork

Configure Feed

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

Read new inner page format

garrison 1e3697e1 89e66f25

+92 -12
+92 -12
lib/btree/iterator.ex
··· 3 3 alias Hobbes.BTree.{Page, Iterator} 4 4 5 5 import ExUnit.Assertions, only: [assert: 1] 6 + import Hobbes.BTree.Utils 6 7 7 8 @type t :: %__MODULE__{ 8 9 } ··· 42 43 43 44 defp seek_forward(%Iterator{} = it, search_key) do 44 45 page_data = it.current_page 45 - {page_type, pairs} = Page.decode_page(page_data) 46 + << 47 + _::binary-size(byte_size(page_data) - c_page_trailer_bytes()), 48 + _::integer-16, 49 + type_byte::integer-8, 50 + >> = page_data 46 51 47 - case page_type do 48 - :inner -> 49 - {i, {_end_key, child_address}} = seek_inner(pairs, search_key, 0) 52 + case type_byte do 53 + 0x00 -> 54 + {i, {_end_key, child_address}} = seek_inner(page_data, search_key) 50 55 <<child_index::integer-64, child_checksum::binary-16>> = child_address 51 56 child_data = BTree.read_page(it.btree.page_store, child_index, child_checksum) 52 57 ··· 57 62 } 58 63 seek_forward(it, search_key) 59 64 60 - :leaf -> 65 + 0x01 -> 66 + {_page_type, pairs} = Page.decode_page(page_data) 61 67 case seek_leaf(pairs, search_key, 0) do 62 68 {i, {_k, _v} = pair} -> 63 69 %{it | ··· 75 81 end 76 82 end 77 83 84 + defp seek_inner(page_data, search_key) do 85 + page_size = byte_size(page_data) 86 + << 87 + _::binary-size(byte_size(page_data) - c_page_trailer_bytes()), 88 + pointer_count::integer-16, 89 + _type::integer-8, 90 + >> = page_data 91 + assert pointer_count > 0 92 + key_count = pointer_count - 1 93 + 94 + slots_start = page_size - (key_count * c_page_slot_entry_bytes()) - c_page_trailer_bytes() 95 + pointers_start = slots_start - (pointer_count * c_inner_pointer_bytes()) 96 + 97 + do_seek_inner(page_data, slots_start, pointers_start, pointer_count, search_key, 0) 98 + end 99 + 100 + defp do_seek_inner(page_data, _slots_start, pointers_start, pointer_count, _search_key, i) 101 + when i == (pointer_count - 1) do 102 + << 103 + _::binary-size(pointers_start + (i * c_inner_pointer_bytes())), 104 + address::binary-24, 105 + _::binary, 106 + >> = page_data 107 + 108 + end_key = nil 109 + {i, {end_key, address}} 110 + end 111 + 112 + defp do_seek_inner(page_data, slots_start, pointers_start, pointer_count, search_key, i) do 113 + << 114 + _::binary-size(slots_start + (i * c_page_slot_entry_bytes())), 115 + key_offset::integer-16, 116 + _::binary, 117 + >> = page_data 118 + << 119 + _::binary-size(key_offset), 120 + key_size::integer-16, 121 + end_key::binary-size(key_size), 122 + _::binary, 123 + >> = page_data 124 + 125 + case search_key < end_key do 126 + true -> 127 + << 128 + _::binary-size(pointers_start + (i * c_inner_pointer_bytes())), 129 + address::binary-24, 130 + _::binary, 131 + >> = page_data 132 + # TODO: unnest 133 + {i, {end_key, address}} 134 + 135 + false -> 136 + i = i + 1 137 + do_seek_inner(page_data, slots_start, pointers_start, pointer_count, search_key, i) 138 + end 139 + end 140 + 78 141 defp seek_inner([], _search_key, _i), do: assert false 79 142 defp seek_inner([{k, _v} = p | pairs_rest], search_key, i) do 80 143 case search_key < k do ··· 96 159 current_page: current_page, 97 160 current_i: current_i, 98 161 } = it 99 - {page_type, pairs} = Page.decode_page(current_page) 100 - pair_count = length(pairs) 162 + << 163 + _::binary-size(byte_size(current_page) - c_page_trailer_bytes()), 164 + # TODO: cache these in the iterator 165 + pair_count::integer-16, 166 + type_byte::integer-8, 167 + >> = current_page 101 168 102 169 case current_i < (pair_count - 1) do 103 170 true -> 104 171 current_i = current_i + 1 105 - current_pair = Enum.at(pairs, current_i) 106 - case page_type do 107 - :inner -> 108 - {_k, <<child_index::integer-64, child_checksum::binary-16>>} = current_pair 172 + case type_byte do 173 + 0x00 -> 174 + page_size = byte_size(current_page) 175 + pointer_count = pair_count 176 + key_count = pointer_count - 1 177 + slots_start = page_size - (key_count * c_page_slot_entry_bytes()) - c_page_trailer_bytes() 178 + pointers_start = slots_start - (pointer_count * c_inner_pointer_bytes()) 179 + 180 + << 181 + _::binary-size(pointers_start + (current_i * c_inner_pointer_bytes())), 182 + child_index::integer-64, 183 + child_checksum::binary-16, 184 + _::binary, 185 + >> = current_page 186 + 109 187 child_page = BTree.read_page(it.btree.page_store, child_index, child_checksum) 110 188 it = %{it | 111 189 page_stack: [{current_i, current_page} | it.page_stack], ··· 115 193 } 116 194 next_forward(it) 117 195 118 - :leaf -> 196 + 0x01 -> 197 + {_type, pairs} = Page.decode_page(current_page) 198 + current_pair = Enum.at(pairs, current_i) 119 199 %{it | 120 200 current_i: current_i, 121 201 current_pair: current_pair,