this repo has no description
2
fork

Configure Feed

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

Decode pages

garrison 80723a34 d2cd3747

+75 -9
+6 -1
lib/btree/btree.ex
··· 98 98 end 99 99 end 100 100 101 - def apply_batch(%BTree{} = _btree, _mutations) do 101 + def apply_batch(%BTree{} = btree, _mutations) do 102 + {root_index, _checksum} = btree.root_address 103 + root_page_data = read_page(btree.page_store, root_index) 104 + {:inner, root_pairs} = Page.decode_page(root_page_data) 105 + dbg root_pairs 106 + 102 107 :ok 103 108 end 104 109 end
+61 -8
lib/btree/page.ex
··· 1 1 defmodule Hobbes.BTree.Page do 2 + import Hobbes.BTree.Utils 2 3 import ExUnit.Assertions, only: [assert: 1] 3 4 4 5 @type page_type :: :inner | :leaf ··· 6 7 defp encode_type(:inner), do: 0x00 7 8 defp encode_type(:leaf), do: 0x01 8 9 9 - def encode_page_from_pairs(type, opt_page_size, pairs) do 10 - type_byte = encode_type(type) 11 - {body, slots, count} = do_encode_page(pairs, "", "", 0) 10 + defp decode_type(0x00), do: :inner 11 + defp decode_type(0x01), do: :leaf 12 + 13 + def encode_page_from_pairs(page_type, opt_page_size, pairs) do 14 + type_byte = encode_type(page_type) 15 + {body, slots, pair_count} = do_encode_page(pairs, "", "", 0) 12 16 13 17 # TODO: probably large enough? 14 - assert count < (2 ** 16) 18 + assert pair_count < (2 ** 16) 19 + # See constant: c_page_trailer_bytes() 15 20 trailer = << 16 - count::integer-16, 21 + pair_count::integer-16, 17 22 type_byte::integer-8, 18 23 >> 19 24 ··· 36 41 end 37 42 38 43 defp do_encode_page([{key, value} | pairs_rest], body_acc, slots_acc, count_acc) do 39 - pos = byte_size(body_acc) 44 + pair_offset = byte_size(body_acc) 40 45 key_size = byte_size(key) 41 46 value_size = byte_size(value) 42 47 43 48 # TODO: larger 44 49 assert key_size < (2 ** 16) 45 50 assert value_size < (2 ** 16) 51 + # See constant: c_page_pair_overhead_bytes() 46 52 body_acc = << 47 53 body_acc::binary, 48 54 key_size::integer-16, ··· 52 58 >> 53 59 54 60 # TODO: support >64KiB pages? 55 - assert pos < (2 ** 16) 61 + assert pair_offset < (2 ** 16) 62 + # See constant: c_page_slot_entry_bytes() 56 63 slots_acc = << 57 64 slots_acc::binary, 58 - pos::integer-16, 65 + pair_offset::integer-16, 59 66 >> 60 67 61 68 count_acc = count_acc + 1 62 69 do_encode_page(pairs_rest, body_acc, slots_acc, count_acc) 70 + end 71 + 72 + def decode_page(page_data) do 73 + page_size = byte_size(page_data) 74 + << 75 + _::binary-size(page_size - c_page_trailer_bytes()), 76 + pair_count::integer-16, 77 + type_byte::integer-8, 78 + >> = page_data 79 + assert pair_count >= 0 80 + page_type = decode_type(type_byte) 81 + 82 + slots_size = pair_count * c_page_slot_entry_bytes() 83 + << 84 + _::binary-size(page_size - slots_size - c_page_trailer_bytes()), 85 + slots_data::binary-size(slots_size), 86 + _trailer::binary, 87 + >> = page_data 88 + 89 + pairs = do_decode_pairs(slots_data, page_data, []) 90 + {page_type, pairs} 91 + end 92 + 93 + defp do_decode_pairs("", _page_data, pairs_acc) do 94 + Enum.reverse(pairs_acc) 95 + end 96 + 97 + defp do_decode_pairs(slots_data, page_data, pairs_acc) do 98 + # See constant: c_page_slot_entry_bytes() 99 + << 100 + pair_offset::integer-16, 101 + slots_rest::binary, 102 + >> = slots_data 103 + 104 + # See constant: c_page_pair_overhead_bytes() 105 + << 106 + _::binary-size(pair_offset), 107 + key_size::integer-16, 108 + value_size::integer-16, 109 + key::binary-size(key_size), 110 + value::binary-size(value_size), 111 + _::binary, 112 + >> = page_data 113 + 114 + pairs_acc = [{key, value} | pairs_acc] 115 + do_decode_pairs(slots_rest, page_data, pairs_acc) 63 116 end 64 117 end
+8
lib/btree/utils.ex
··· 1 + defmodule Hobbes.BTree.Utils do 2 + # pair_count + type_byte 3 + defmacro c_page_trailer_bytes, do: 2 + 1 4 + # key_size + value_size 5 + defmacro c_page_pair_overhead_bytes, do: 2 + 2 6 + # pair_offset 7 + defmacro c_page_slot_entry_bytes, do: 2 8 + end