authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2019-05-01 23:38:52-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2019-05-01 23:46:52-07:00
log8b7c59a41419b8802af843ac023ba0c6fbfbb83b
treee89097419e5c6f6b44c902bc3962e8d6805a3a60
parentc00c18de6a5e436b1c362c06d6e5259c8f731a90

std.HashMap: add public ensureCapacity fn


1 files changed, 20 insertions(+), 10 deletions(-)

std/hash_map.zig+20-10
...@@ -118,7 +118,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -118,7 +118,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
118 };118 };
119 }119 }
120 self.incrementModificationCount();120 self.incrementModificationCount();
121 try self.ensureCapacity();121 try self.autoCapacity();
122 const put_result = self.internalPut(key);122 const put_result = self.internalPut(key);
123 assert(put_result.old_kv == null);123 assert(put_result.old_kv == null);
124 return GetOrPutResult{124 return GetOrPutResult{
...@@ -135,15 +135,15 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -135,15 +135,15 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
135 return res.kv;135 return res.kv;
136 }136 }
137137
138 fn ensureCapacity(self: *Self) !void {138 /// Sets the capacity to the new capacity if the new
139 if (self.entries.len == 0) {139 /// capacity is greater than the current capacity.
140 return self.initCapacity(16);140 pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {
141 if (new_capacity <= self.entries.len) {
142 return;
141 }143 }
142144 const old_entries = self.entries;
143 // if we get too full (60%), double the capacity145 try self.initCapacity(new_capacity);
144 if (self.size * 5 >= self.entries.len * 3) {146 if (old_entries.len > 0) {
145 const old_entries = self.entries;
146 try self.initCapacity(self.entries.len * 2);
147 // dump all of the old elements into the new table147 // dump all of the old elements into the new table
148 for (old_entries) |*old_entry| {148 for (old_entries) |*old_entry| {
149 if (old_entry.used) {149 if (old_entry.used) {
...@@ -157,7 +157,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -157,7 +157,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
157 /// Returns the kv pair that was already there.157 /// Returns the kv pair that was already there.
158 pub fn put(self: *Self, key: K, value: V) !?KV {158 pub fn put(self: *Self, key: K, value: V) !?KV {
159 self.incrementModificationCount();159 self.incrementModificationCount();
160 try self.ensureCapacity();160 try self.autoCapacity();
161161
162 const put_result = self.internalPut(key);162 const put_result = self.internalPut(key);
163 put_result.new_entry.kv.value = value;163 put_result.new_entry.kv.value = value;
...@@ -227,6 +227,16 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -227,6 +227,16 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
227 return other;227 return other;
228 }228 }
229229
230 fn autoCapacity(self: *Self) !void {
231 if (self.entries.len == 0) {
232 return self.ensureCapacity(16);
233 }
234 // if we get too full (60%), double the capacity
235 if (self.size * 5 >= self.entries.len * 3) {
236 return self.ensureCapacity(self.entries.len * 2);
237 }
238 }
239
230 fn initCapacity(hm: *Self, capacity: usize) !void {240 fn initCapacity(hm: *Self, capacity: usize) !void {
231 hm.entries = try hm.allocator.alloc(Entry, capacity);241 hm.entries = try hm.allocator.alloc(Entry, capacity);
232 hm.size = 0;242 hm.size = 0;