this repo has no description
2
fork

Configure Feed

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

Decode leaf pairs in-place while iterating

garrison f27c9d35 f949d48b

+57 -7
+57 -7
lib/btree/iterator.ex
··· 1 1 defmodule Hobbes.BTree.Iterator do 2 2 alias Hobbes.BTree 3 - alias Hobbes.BTree.{Page, Iterator} 3 + alias Hobbes.BTree.Iterator 4 4 5 5 import ExUnit.Assertions, only: [assert: 1] 6 6 import Hobbes.BTree.Utils ··· 45 45 page_data = it.current_page 46 46 << 47 47 _::binary-size(byte_size(page_data) - c_page_trailer_bytes()), 48 - _::integer-16, 48 + pair_count::integer-16, 49 49 type_byte::integer-8, 50 50 >> = page_data 51 51 ··· 63 63 seek_forward(it, search_key) 64 64 65 65 0x01 -> 66 - {_page_type, pairs} = Page.decode_page(page_data) 67 - case seek_leaf(pairs, search_key, 0) do 66 + case seek_leaf(page_data, pair_count, search_key) do 68 67 {i, {_k, _v} = pair} -> 69 68 %{it | 70 69 current_i: i, ··· 74 73 :not_found -> 75 74 it = %{it | 76 75 # TODO: kinda sus to use an out-of-bounds i but the page could be empty 77 - current_i: length(pairs), 76 + current_i: pair_count, 78 77 } 79 78 next_forward(it) 80 79 end ··· 139 138 end 140 139 end 141 140 141 + defp seek_leaf(page_data, pair_count, search_key) do 142 + page_size = byte_size(page_data) 143 + 144 + slots_start = page_size - (pair_count * c_page_slot_entry_bytes()) - c_page_trailer_bytes() 145 + do_seek_leaf(page_data, slots_start, pair_count, search_key, 0) 146 + end 147 + 148 + defp do_seek_leaf(_page_data, _slots_start, pair_count, _search_key, i) when i == pair_count do 149 + :not_found 150 + end 151 + 152 + defp do_seek_leaf(page_data, slots_start, pair_count, search_key, i) do 153 + assert i < pair_count 154 + << 155 + _prefix::binary-size(slots_start + (i * c_page_slot_entry_bytes())), 156 + pair_offset::integer-16, 157 + _rest::binary, 158 + >> = page_data 159 + 160 + << 161 + _prefix::binary-size(pair_offset), 162 + key_size::integer-16, 163 + value_size::integer-16, 164 + key::binary-size(key_size), 165 + value::binary-size(value_size), 166 + _rest::binary, 167 + >> = page_data 168 + 169 + case key >= search_key do 170 + true -> {i, {key, value}} 171 + false -> do_seek_leaf(page_data, slots_start, pair_count, search_key, i + 1) 172 + end 173 + end 174 + 142 175 defp seek_inner([], _search_key, _i), do: assert false 143 176 defp seek_inner([{k, _v} = p | pairs_rest], search_key, i) do 144 177 case search_key < k do ··· 195 228 next_forward(it) 196 229 197 230 0x01 -> 198 - {_type, pairs} = Page.decode_page(current_page) 199 - current_pair = Enum.at(pairs, current_i) 231 + page_size = byte_size(current_page) 232 + slots_start = page_size - (pair_count * c_page_slot_entry_bytes()) - c_page_trailer_bytes() 233 + 234 + << 235 + _prefix::binary-size(slots_start + (current_i * c_page_slot_entry_bytes())), 236 + pair_offset::integer-16, 237 + _rest::binary, 238 + >> = current_page 239 + 240 + << 241 + _prefix::binary-size(pair_offset), 242 + key_size::integer-16, 243 + value_size::integer-16, 244 + key::binary-size(key_size), 245 + value::binary-size(value_size), 246 + _rest::binary, 247 + >> = current_page 248 + current_pair = {key, value} 249 + 200 250 %{it | 201 251 current_i: current_i, 202 252 current_pair: current_pair,