authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-07 09:53:52-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-07 09:53:52-04:00
log81007d0a4beed18314e948d3afbcdc7a8cfd73a9
tree5bcddc0efd4438221d69054c259321206141ae8e
parent41e1cd185b82a518c58c92544c45f0348c03ef74

SegmentedList: fixups from review comments


1 files changed, 15 insertions(+), 11 deletions(-)

std/segmented_list.zig+15-11
...@@ -18,12 +18,12 @@ const Allocator = std.mem.Allocator;...@@ -18,12 +18,12 @@ const Allocator = std.mem.Allocator;
18// ...18// ...
19//19//
20// warehouse indexes:20// warehouse indexes:
21// shelf 0: 021// shelf 0: 0
22// shelf 1: 0 122// shelf 1: 0 1
23// shelf 2: 0 1 2 323// shelf 2: 0 1 2 3
24// shelf 3: 0 1 2 3 4 5 6 724// shelf 3: 0 1 2 3 4 5 6 7
25// shelf 4: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1525// shelf 4: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
26// shelf 5: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3126// shelf 5: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
27// ...27// ...
28//28//
29// With this arrangement, here are the equations to get the shelf index and29// With this arrangement, here are the equations to get the shelf index and
...@@ -66,6 +66,8 @@ const Allocator = std.mem.Allocator;...@@ -66,6 +66,8 @@ const Allocator = std.mem.Allocator;
66///66///
67/// Because it never has to copy elements from an old location to a new location, it does not require67/// Because it never has to copy elements from an old location to a new location, it does not require
68/// its elements to be copyable, and it avoids wasting memory when backed by an ArenaAllocator.68/// its elements to be copyable, and it avoids wasting memory when backed by an ArenaAllocator.
69/// Note that the push() and pop() convenience methods perform a copy, but you can instead use
70/// addOne(), at(), setCapacity(), and shrinkCapacity() to avoid copying items.
69///71///
70/// This data structure has O(1) push and O(1) pop.72/// This data structure has O(1) push and O(1) pop.
71///73///
...@@ -74,8 +76,10 @@ const Allocator = std.mem.Allocator;...@@ -74,8 +76,10 @@ const Allocator = std.mem.Allocator;
74pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {76pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type {
75 return struct {77 return struct {
76 const Self = this;78 const Self = this;
77 const prealloc_base = blk: {79 const prealloc_exp = blk: {
80 // we don't use the prealloc_exp constant when prealloc_item_count is 0.
78 assert(prealloc_item_count != 0);81 assert(prealloc_item_count != 0);
82
79 const value = std.math.log2_int(usize, prealloc_item_count);83 const value = std.math.log2_int(usize, prealloc_item_count);
80 assert((1 << value) == prealloc_item_count); // prealloc_item_count must be a power of 284 assert((1 << value) == prealloc_item_count); // prealloc_item_count must be a power of 2
81 break :blk @typeOf(1)(value);85 break :blk @typeOf(1)(value);
...@@ -190,28 +194,28 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -190,28 +194,28 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
190 if (prealloc_item_count == 0) {194 if (prealloc_item_count == 0) {
191 return std.math.log2_int_ceil(usize, box_count + 1);195 return std.math.log2_int_ceil(usize, box_count + 1);
192 }196 }
193 return std.math.log2_int_ceil(usize, box_count + prealloc_item_count) - prealloc_base - 1;197 return std.math.log2_int_ceil(usize, box_count + prealloc_item_count) - prealloc_exp - 1;
194 }198 }
195199
196 fn shelfSize(shelf_index: ShelfIndex) usize {200 fn shelfSize(shelf_index: ShelfIndex) usize {
197 if (prealloc_item_count == 0) {201 if (prealloc_item_count == 0) {
198 return usize(1) << shelf_index;202 return usize(1) << shelf_index;
199 }203 }
200 return usize(1) << (shelf_index + (prealloc_base + 1));204 return usize(1) << (shelf_index + (prealloc_exp + 1));
201 }205 }
202206
203 fn shelfIndex(list_index: usize) ShelfIndex {207 fn shelfIndex(list_index: usize) ShelfIndex {
204 if (prealloc_item_count == 0) {208 if (prealloc_item_count == 0) {
205 return std.math.log2_int(usize, list_index + 1);209 return std.math.log2_int(usize, list_index + 1);
206 }210 }
207 return std.math.log2_int(usize, list_index + prealloc_item_count) - prealloc_base - 1;211 return std.math.log2_int(usize, list_index + prealloc_item_count) - prealloc_exp - 1;
208 }212 }
209213
210 fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {214 fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {
211 if (prealloc_item_count == 0) {215 if (prealloc_item_count == 0) {
212 return (list_index + 1) - (usize(1) << shelf_index);216 return (list_index + 1) - (usize(1) << shelf_index);
213 }217 }
214 return list_index + prealloc_item_count - (usize(1) << ((prealloc_base + 1) + shelf_index));218 return list_index + prealloc_item_count - (usize(1) << ((prealloc_exp + 1) + shelf_index));
215 }219 }
216220
217 fn freeShelves(self: &Self, from_count: ShelfIndex, to_count: ShelfIndex) void {221 fn freeShelves(self: &Self, from_count: ShelfIndex, to_count: ShelfIndex) void {