| ... | ... | @@ -604,6 +604,8 @@ pub fn ArrayHashMapUnmanaged( |
| 604 | 604 | ordered, |
| 605 | 605 | }; |
| 606 | 606 | |
| 607 | const Oom = Allocator.Error; |
| 608 | |
| 607 | 609 | /// Convert from an unmanaged map to a managed map. After calling this, |
| 608 | 610 | /// the promoted map should no longer be used. |
| 609 | 611 | pub fn promote(self: Self, allocator: Allocator) Managed { |
| ... | ... | @@ -619,14 +621,14 @@ pub fn ArrayHashMapUnmanaged( |
| 619 | 621 | }; |
| 620 | 622 | } |
| 621 | 623 | |
| 622 | | pub fn init(allocator: Allocator, key_list: []const K, value_list: []const V) !Self { |
| 624 | pub fn init(allocator: Allocator, key_list: []const K, value_list: []const V) Oom!Self { |
| 623 | 625 | var self: Self = .{}; |
| 624 | 626 | errdefer self.deinit(allocator); |
| 625 | 627 | try self.reinit(allocator, key_list, value_list); |
| 626 | 628 | return self; |
| 627 | 629 | } |
| 628 | 630 | |
| 629 | | pub fn reinit(self: *Self, allocator: Allocator, key_list: []const K, value_list: []const V) !void { |
| 631 | pub fn reinit(self: *Self, allocator: Allocator, key_list: []const K, value_list: []const V) Oom!void { |
| 630 | 632 | try self.entries.resize(allocator, key_list.len); |
| 631 | 633 | @memcpy(self.keys(), key_list); |
| 632 | 634 | if (@sizeOf(V) != 0) { |
| ... | ... | @@ -750,24 +752,24 @@ pub fn ArrayHashMapUnmanaged( |
| 750 | 752 | /// Otherwise, puts a new item with undefined value, and |
| 751 | 753 | /// the `Entry` pointer points to it. Caller should then initialize |
| 752 | 754 | /// the value (but not the key). |
| 753 | | pub fn getOrPut(self: *Self, allocator: Allocator, key: K) !GetOrPutResult { |
| 755 | pub fn getOrPut(self: *Self, allocator: Allocator, key: K) Oom!GetOrPutResult { |
| 754 | 756 | if (@sizeOf(Context) != 0) |
| 755 | 757 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead."); |
| 756 | 758 | return self.getOrPutContext(allocator, key, undefined); |
| 757 | 759 | } |
| 758 | | pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) !GetOrPutResult { |
| 760 | pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) Oom!GetOrPutResult { |
| 759 | 761 | const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx); |
| 760 | 762 | if (!gop.found_existing) { |
| 761 | 763 | gop.key_ptr.* = key; |
| 762 | 764 | } |
| 763 | 765 | return gop; |
| 764 | 766 | } |
| 765 | | pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult { |
| 767 | pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) Oom!GetOrPutResult { |
| 766 | 768 | if (@sizeOf(Context) != 0) |
| 767 | 769 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead."); |
| 768 | 770 | return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined); |
| 769 | 771 | } |
| 770 | | pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult { |
| 772 | pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) Oom!GetOrPutResult { |
| 771 | 773 | self.ensureTotalCapacityContext(allocator, self.entries.len + 1, ctx) catch |err| { |
| 772 | 774 | // "If key exists this function cannot fail." |
| 773 | 775 | const index = self.getIndexAdapted(key, key_ctx) orelse return err; |
| ... | ... | @@ -848,12 +850,12 @@ pub fn ArrayHashMapUnmanaged( |
| 848 | 850 | } |
| 849 | 851 | } |
| 850 | 852 | |
| 851 | | pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) !GetOrPutResult { |
| 853 | pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) Oom!GetOrPutResult { |
| 852 | 854 | if (@sizeOf(Context) != 0) |
| 853 | 855 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead."); |
| 854 | 856 | return self.getOrPutValueContext(allocator, key, value, undefined); |
| 855 | 857 | } |
| 856 | | pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !GetOrPutResult { |
| 858 | pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Oom!GetOrPutResult { |
| 857 | 859 | const res = try self.getOrPutContextAdapted(allocator, key, ctx, ctx); |
| 858 | 860 | if (!res.found_existing) { |
| 859 | 861 | res.key_ptr.* = key; |
| ... | ... | @@ -864,12 +866,12 @@ pub fn ArrayHashMapUnmanaged( |
| 864 | 866 | |
| 865 | 867 | /// Increases capacity, guaranteeing that insertions up until the |
| 866 | 868 | /// `expected_count` will not cause an allocation, and therefore cannot fail. |
| 867 | | pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) !void { |
| 869 | pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Oom!void { |
| 868 | 870 | if (@sizeOf(ByIndexContext) != 0) |
| 869 | 871 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead."); |
| 870 | 872 | return self.ensureTotalCapacityContext(allocator, new_capacity, undefined); |
| 871 | 873 | } |
| 872 | | pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_capacity: usize, ctx: Context) !void { |
| 874 | pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_capacity: usize, ctx: Context) Oom!void { |
| 873 | 875 | self.pointer_stability.lock(); |
| 874 | 876 | defer self.pointer_stability.unlock(); |
| 875 | 877 | |
| ... | ... | @@ -901,7 +903,7 @@ pub fn ArrayHashMapUnmanaged( |
| 901 | 903 | self: *Self, |
| 902 | 904 | allocator: Allocator, |
| 903 | 905 | additional_capacity: usize, |
| 904 | | ) !void { |
| 906 | ) Oom!void { |
| 905 | 907 | if (@sizeOf(Context) != 0) |
| 906 | 908 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead."); |
| 907 | 909 | return self.ensureUnusedCapacityContext(allocator, additional_capacity, undefined); |
| ... | ... | @@ -911,7 +913,7 @@ pub fn ArrayHashMapUnmanaged( |
| 911 | 913 | allocator: Allocator, |
| 912 | 914 | additional_capacity: usize, |
| 913 | 915 | ctx: Context, |
| 914 | | ) !void { |
| 916 | ) Oom!void { |
| 915 | 917 | return self.ensureTotalCapacityContext(allocator, self.count() + additional_capacity, ctx); |
| 916 | 918 | } |
| 917 | 919 | |
| ... | ... | @@ -926,24 +928,24 @@ pub fn ArrayHashMapUnmanaged( |
| 926 | 928 | |
| 927 | 929 | /// Clobbers any existing data. To detect if a put would clobber |
| 928 | 930 | /// existing data, see `getOrPut`. |
| 929 | | pub fn put(self: *Self, allocator: Allocator, key: K, value: V) !void { |
| 931 | pub fn put(self: *Self, allocator: Allocator, key: K, value: V) Oom!void { |
| 930 | 932 | if (@sizeOf(Context) != 0) |
| 931 | 933 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead."); |
| 932 | 934 | return self.putContext(allocator, key, value, undefined); |
| 933 | 935 | } |
| 934 | | pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void { |
| 936 | pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Oom!void { |
| 935 | 937 | const result = try self.getOrPutContext(allocator, key, ctx); |
| 936 | 938 | result.value_ptr.* = value; |
| 937 | 939 | } |
| 938 | 940 | |
| 939 | 941 | /// Inserts a key-value pair into the hash map, asserting that no previous |
| 940 | 942 | /// entry with the same key is already present |
| 941 | | pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) !void { |
| 943 | pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) Oom!void { |
| 942 | 944 | if (@sizeOf(Context) != 0) |
| 943 | 945 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead."); |
| 944 | 946 | return self.putNoClobberContext(allocator, key, value, undefined); |
| 945 | 947 | } |
| 946 | | pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void { |
| 948 | pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Oom!void { |
| 947 | 949 | const result = try self.getOrPutContext(allocator, key, ctx); |
| 948 | 950 | assert(!result.found_existing); |
| 949 | 951 | result.value_ptr.* = value; |
| ... | ... | @@ -977,12 +979,12 @@ pub fn ArrayHashMapUnmanaged( |
| 977 | 979 | } |
| 978 | 980 | |
| 979 | 981 | /// Inserts a new `Entry` into the hash map, returning the previous one, if any. |
| 980 | | pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) !?KV { |
| 982 | pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) Oom!?KV { |
| 981 | 983 | if (@sizeOf(Context) != 0) |
| 982 | 984 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead."); |
| 983 | 985 | return self.fetchPutContext(allocator, key, value, undefined); |
| 984 | 986 | } |
| 985 | | pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !?KV { |
| 987 | pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Oom!?KV { |
| 986 | 988 | const gop = try self.getOrPutContext(allocator, key, ctx); |
| 987 | 989 | var result: ?KV = null; |
| 988 | 990 | if (gop.found_existing) { |
| ... | ... | @@ -1269,12 +1271,12 @@ pub fn ArrayHashMapUnmanaged( |
| 1269 | 1271 | /// Create a copy of the hash map which can be modified separately. |
| 1270 | 1272 | /// The copy uses the same context as this instance, but is allocated |
| 1271 | 1273 | /// with the provided allocator. |
| 1272 | | pub fn clone(self: Self, allocator: Allocator) !Self { |
| 1274 | pub fn clone(self: Self, allocator: Allocator) Oom!Self { |
| 1273 | 1275 | if (@sizeOf(ByIndexContext) != 0) |
| 1274 | 1276 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead."); |
| 1275 | 1277 | return self.cloneContext(allocator, undefined); |
| 1276 | 1278 | } |
| 1277 | | pub fn cloneContext(self: Self, allocator: Allocator, ctx: Context) !Self { |
| 1279 | pub fn cloneContext(self: Self, allocator: Allocator, ctx: Context) Oom!Self { |
| 1278 | 1280 | var other: Self = .{}; |
| 1279 | 1281 | other.entries = try self.entries.clone(allocator); |
| 1280 | 1282 | errdefer other.entries.deinit(allocator); |
| ... | ... | @@ -1308,13 +1310,13 @@ pub fn ArrayHashMapUnmanaged( |
| 1308 | 1310 | /// directly without going through the methods of this map. |
| 1309 | 1311 | /// |
| 1310 | 1312 | /// The time complexity of this operation is O(n). |
| 1311 | | pub fn reIndex(self: *Self, allocator: Allocator) !void { |
| 1313 | pub fn reIndex(self: *Self, allocator: Allocator) Oom!void { |
| 1312 | 1314 | if (@sizeOf(ByIndexContext) != 0) |
| 1313 | 1315 | @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call reIndexContext instead."); |
| 1314 | 1316 | return self.reIndexContext(allocator, undefined); |
| 1315 | 1317 | } |
| 1316 | 1318 | |
| 1317 | | pub fn reIndexContext(self: *Self, allocator: Allocator, ctx: Context) !void { |
| 1319 | pub fn reIndexContext(self: *Self, allocator: Allocator, ctx: Context) Oom!void { |
| 1318 | 1320 | // Recompute all hashes. |
| 1319 | 1321 | if (store_hash) { |
| 1320 | 1322 | for (self.keys(), self.entries.items(.hash)) |key, *hash| { |
| ... | ... | @@ -2090,7 +2092,7 @@ const IndexHeader = struct { |
| 2090 | 2092 | return @as(u32, @intCast(self.length() - 1)); |
| 2091 | 2093 | } |
| 2092 | 2094 | |
| 2093 | | fn findBitIndex(desired_capacity: usize) !u8 { |
| 2095 | fn findBitIndex(desired_capacity: usize) Allocator.Error!u8 { |
| 2094 | 2096 | if (desired_capacity > max_capacity) return error.OutOfMemory; |
| 2095 | 2097 | var new_bit_index = @as(u8, @intCast(std.math.log2_int_ceil(usize, desired_capacity))); |
| 2096 | 2098 | if (desired_capacity > index_capacities[new_bit_index]) new_bit_index += 1; |
| ... | ... | @@ -2101,7 +2103,7 @@ const IndexHeader = struct { |
| 2101 | 2103 | |
| 2102 | 2104 | /// Allocates an index header, and fills the entryIndexes array with empty. |
| 2103 | 2105 | /// The distance array contents are undefined. |
| 2104 | | fn alloc(allocator: Allocator, new_bit_index: u8) !*IndexHeader { |
| 2106 | fn alloc(allocator: Allocator, new_bit_index: u8) Allocator.Error!*IndexHeader { |
| 2105 | 2107 | const len = @as(usize, 1) << @as(math.Log2Int(usize), @intCast(new_bit_index)); |
| 2106 | 2108 | const index_size = hash_map.capacityIndexSize(new_bit_index); |
| 2107 | 2109 | const nbytes = @sizeOf(IndexHeader) + index_size * len; |