this repo has no description
2
fork

Configure Feed

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

Buffer pair offsets as a list to prepare for page splits

garrison 03952cda 94446ea9

+48 -33
+2 -2
lib/btree/btree.ex
··· 68 68 69 69 [root_index, leaf_index] = FreeList.reserve_pages(free_list, 2) 70 70 71 - leaf_data = Page.encode_page_from_pairs(:leaf, opt_page_size, []) 71 + [leaf_data] = Page.encode_page_from_pairs(:leaf, opt_page_size, []) 72 72 leaf_checksum = checksum(leaf_data) 73 73 :ok = write_page(page_store, leaf_index, leaf_data) 74 74 ··· 76 76 leaf_address = <<leaf_index::integer-64, leaf_checksum::binary-16>> 77 77 78 78 root_pairs = [{leaf_end_key, leaf_address}] 79 - root_data = Page.encode_page_from_pairs(:inner, opt_page_size, root_pairs) 79 + [root_data] = Page.encode_page_from_pairs(:inner, opt_page_size, root_pairs) 80 80 root_checksum = checksum(root_data) 81 81 :ok = write_page(page_store, root_index, root_data) 82 82
+45 -30
lib/btree/page.ex
··· 12 12 13 13 def encode_page_from_pairs(page_type, opt_page_size, pairs) do 14 14 type_byte = encode_type(page_type) 15 - {body, slots, pair_count} = do_encode_page(pairs, "", "", 0) 15 + {body, offsets, pair_count} = do_encode_page(pairs, "", [], 0) 16 + 17 + maybe_split(opt_page_size, type_byte, body, offsets, pair_count) 18 + end 16 19 17 - # TODO: probably large enough? 18 - assert pair_count < (2 ** 16) 19 - # See constant: c_page_trailer_bytes() 20 - trailer = << 21 - pair_count::integer-16, 22 - type_byte::integer-8, 23 - >> 20 + defp maybe_split(opt_page_size, type_byte, body, offsets, pair_count) do 21 + data_size = byte_size(body) + (pair_count * c_page_slot_entry_bytes()) + c_page_trailer_bytes() 22 + 23 + case data_size > opt_page_size do 24 + true -> 25 + assert false 24 26 25 - pad_bytes = opt_page_size - byte_size(body) - byte_size(slots) - byte_size(trailer) 26 - assert pad_bytes >= 0 27 + false -> 28 + pad_bytes = opt_page_size - data_size 29 + assert pad_bytes >= 0 30 + 31 + page_data = << 32 + body::binary, 33 + 0::integer-unit(8)-size(pad_bytes), 34 + >> 35 + page_data = encode_slots(offsets, page_data) 36 + 37 + assert pair_count < (2 ** 16) 38 + # See constant: c_page_trailer_bytes() 39 + page_data = << 40 + page_data::binary, 41 + pair_count::integer-16, 42 + type_byte::integer-8, 43 + >> 44 + 45 + [page_data] 46 + end 47 + end 27 48 28 - page_data = << 29 - body::binary, 30 - 0::integer-unit(8)-size(pad_bytes), 31 - slots::binary, 32 - trailer::binary, 49 + defp encode_slots([], acc), do: acc 50 + defp encode_slots([offset | offsets_rest], acc) do 51 + assert offset < (2 ** 16) 52 + # See constant: c_page_slot_entry_bytes() 53 + acc = << 54 + acc::binary, 55 + offset::integer-16, 33 56 >> 34 - assert byte_size(page_data) == opt_page_size 35 - 36 - page_data 57 + encode_slots(offsets_rest, acc) 37 58 end 38 59 39 - defp do_encode_page([], body_acc, slots_acc, count_acc) do 40 - {body_acc, slots_acc, count_acc} 60 + defp do_encode_page([], body_acc, offsets_acc, count_acc) do 61 + {body_acc, Enum.reverse(offsets_acc), count_acc} 41 62 end 42 63 43 - defp do_encode_page([{key, value} | pairs_rest], body_acc, slots_acc, count_acc) do 64 + defp do_encode_page([{key, value} | pairs_rest], body_acc, offsets_acc, count_acc) do 44 65 pair_offset = byte_size(body_acc) 45 66 key_size = byte_size(key) 46 67 value_size = byte_size(value) ··· 57 78 value::binary, 58 79 >> 59 80 60 - # TODO: support >64KiB pages? 61 - assert pair_offset < (2 ** 16) 62 - # See constant: c_page_slot_entry_bytes() 63 - slots_acc = << 64 - slots_acc::binary, 65 - pair_offset::integer-16, 66 - >> 67 - 81 + offsets_acc = [pair_offset | offsets_acc] 68 82 count_acc = count_acc + 1 69 - do_encode_page(pairs_rest, body_acc, slots_acc, count_acc) 83 + 84 + do_encode_page(pairs_rest, body_acc, offsets_acc, count_acc) 70 85 end 71 86 72 87 def decode_page(page_data) do
+1 -1
lib/btree/writer.ex
··· 39 39 :leaf -> fill_leaf(btree.write_buffer, page_ek, pairs) 40 40 end 41 41 42 - new_page_data = Page.encode_page_from_pairs(page_type, btree.opts.page_size, pairs) 42 + [new_page_data] = Page.encode_page_from_pairs(page_type, btree.opts.page_size, pairs) 43 43 [new_page_index] = FreeList.reserve_pages(btree.free_list, 1) 44 44 new_page_checksum = BTree.checksum(new_page_data) 45 45 :ok = BTree.write_page(btree.page_store, new_page_index, new_page_data)