this repo has no description
2
fork

Configure Feed

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

Write inner pages

garrison 89e66f25 62af9005

+42 -27
+2 -2
lib/btree/btree.ex
··· 1 1 defmodule Hobbes.BTree do 2 2 alias Hobbes.BTree 3 - alias Hobbes.BTree.{FreeList, Page} 3 + alias Hobbes.BTree.{FreeList, Page, Writer} 4 4 5 5 import ExUnit.Assertions, only: [assert: 1] 6 6 ··· 78 78 leaf_address = <<leaf_index::integer-64, leaf_checksum::binary-16>> 79 79 80 80 root_pairs = [{leaf_end_key, leaf_address}] 81 - [{_ek, root_data}] = Page.encode_page_from_pairs(:inner, opt_page_size, root_pairs, @keyspace_end_key) 81 + [{_ek, root_data}] = Writer.write_root(btree, root_pairs) 82 82 root_checksum = checksum(root_data) 83 83 :ok = write_page(page_store, root_index, root_data) 84 84
+40 -25
lib/btree/writer.ex
··· 69 69 defp do_flush(%BTree{} = btree, page_index, page_checksum, page_sk, page_ek) do 70 70 %{ 71 71 page_store: page_store, 72 + free_list: free_list, 72 73 opts: %{ 73 74 page_size: opt_page_size, 74 75 }, ··· 83 84 type_byte::integer-8, 84 85 >> = page_data 85 86 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 87 + new_pages = 88 + case type_byte do 89 + 0x00 -> flush_inner(btree, page_data, page_sk, page_ek) 90 + 0x01 -> do_flush_leaf(btree, page_data, page_sk, page_ek) 91 + end 92 + 93 + new_indices = FreeList.reserve_pages(free_list, length(new_pages)) 94 + Enum.zip(new_pages, new_indices) 95 + |> Enum.map(fn {{ek, data}, index} -> 96 + :ok = BTree.write_page(page_store, index, data) 97 + 98 + checksum = BTree.checksum(data) 99 + {ek, <<index::integer-64, checksum::binary-16>>} 100 + end) 90 101 end 91 102 92 103 defp flush_inner(%BTree{} = btree, page_data, page_sk, page_ek) do ··· 107 118 assert type_byte == 0x00 108 119 109 120 key_count = pointer_count - 1 110 - slots_start = opt_page_size - (key_count * c_page_slot_entry_bytes()) 121 + slots_start = opt_page_size - (key_count * c_page_slot_entry_bytes()) - c_page_trailer_bytes() 111 122 pointers_start = slots_start - (pointer_count * c_inner_pointer_bytes()) 112 123 113 - writes = collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, [], page_sk, 0) 124 + pairs = collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, [], page_sk, 0) 125 + write_inner(btree, page_ek, pairs) 114 126 end 115 127 116 128 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 129 + when i == pointer_count do 118 130 Enum.reverse(writes_acc) 119 131 end 120 132 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 133 + defp collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, pairs_acc, start_key, i) do 122 134 assert i < pointer_count 123 135 end_key = inner_end_key(page_data, page_ek, slots_start, key_count, i) 136 + << 137 + _::binary-size(pointers_start + (i * c_inner_pointer_bytes())), 138 + address::binary-24, 139 + _::binary, 140 + >> = page_data 124 141 125 142 case :ets.first(write_buffer) do 126 143 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) 144 + << 145 + index::integer-64, 146 + checksum::binary-16, 147 + >> = address 148 + new_pairs = do_flush(btree, index, checksum, start_key, end_key) 129 149 130 - writes_acc = [{i, addresses} | writes_acc] 150 + pairs_acc = Enum.reverse(new_pairs, pairs_acc) 131 151 start_key = end_key 132 152 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) 153 + collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, pairs_acc, start_key, i) 134 154 135 155 _ -> 156 + pairs_acc = [{end_key, address} | pairs_acc] 136 157 start_key = end_key 137 158 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) 159 + collect_inner_writes(btree, write_buffer, page_data, page_ek, slots_start, pointers_start, key_count, pointer_count, pairs_acc, start_key, i) 139 160 end 140 161 end 141 162 ··· 149 170 end 150 171 end 151 172 152 - defp do_flush_leaf(btree, page_data, page_sk, page_ek) do 173 + defp do_flush_leaf(btree, page_data, _page_sk, page_ek) do 153 174 {page_type, pairs} = Page.decode_page(page_data) 154 175 assert page_type == :leaf 155 176 156 177 pairs = fill_leaf(btree.write_buffer, page_ek, pairs) 157 178 158 - new_encoded_pages = Page.encode_page_from_pairs(page_type, btree.opts.page_size, pairs, page_ek) 159 - assert elem(List.last(new_encoded_pages), 0) == page_ek 160 - new_indices = FreeList.reserve_pages(btree.free_list, length(new_encoded_pages)) 161 - 162 - Enum.zip(new_encoded_pages, new_indices) 163 - |> Enum.map(fn {{ek, data}, index} -> 164 - :ok = BTree.write_page(btree.page_store, index, data) 165 - 166 - checksum = BTree.checksum(data) 167 - {ek, <<index::integer-64, checksum::binary-16>>} 168 - end) 179 + Page.encode_page_from_pairs(page_type, btree.opts.page_size, pairs, page_ek) 169 180 end 170 181 171 182 defp fill_inner(%BTree{} = btree, pairs, page_sk, page_ek, writes_acc) do ··· 201 212 202 213 _ -> pairs_acc 203 214 end 215 + end 216 + 217 + def write_root(%BTree{} = btree, pairs) do 218 + write_inner(btree, "\xFF\xFF\xFF\xFF", pairs) 204 219 end 205 220 206 221 defp write_inner(%BTree{} = btree, end_key, pairs) do