this repo has no description
2
fork

Configure Feed

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

Re-use freed pages in BTree.FreeList

garrison 66c99ccd d7ae120f

+40
+40
lib/btree/free_list.ex
··· 107 107 108 108 @spec reserve_pages(t, non_neg_integer) :: [non_neg_integer] 109 109 def reserve_pages(free_list, count) do 110 + {freed_indexes, reserved_count} = do_reserve_free_pages(free_list, count, [], 0) 111 + 112 + case reserved_count == count do 113 + true -> 114 + freed_indexes 115 + 116 + false -> 117 + assert reserved_count < count 118 + 119 + allocated_indexes = allocate_new_pages(free_list, count - reserved_count) 120 + Enum.reverse(freed_indexes, allocated_indexes) 121 + end 122 + 110 123 [{:max_index, max_index}] = :ets.lookup(free_list, :max_index) 111 124 112 125 :ets.insert(free_list, {:max_index, max_index + count}) 113 126 Enum.to_list((max_index + 1)..(max_index + count)) 127 + end 128 + 129 + defp allocate_new_pages(free_list, count) do 130 + [{:max_index, old_max_index}] = :ets.lookup(free_list, :max_index) 131 + new_max_index = old_max_index + count 132 + 133 + :ets.insert(free_list, {:max_index, new_max_index}) 134 + Enum.to_list(old_max_index..(new_max_index - 1)) 135 + end 136 + 137 + defp do_reserve_free_pages(_free_list, target_count, acc, count_acc) 138 + when count_acc == target_count do 139 + {acc, count_acc} 140 + end 141 + 142 + defp do_reserve_free_pages(free_list, target_count, acc, count_acc) do 143 + case :ets.next(free_list, [:free | -1]) do 144 + [:free | index] = key -> 145 + :ets.delete(free_list, key) 146 + 147 + acc = [index | acc] 148 + count_acc = count_acc + 1 149 + do_reserve_free_pages(free_list, target_count, acc, count_acc) 150 + 151 + _ -> 152 + {acc, count_acc} 153 + end 114 154 end 115 155 116 156 @spec free_page(t, non_neg_integer) :: :ok