* Add a value to the PrefixMap. Returns true if the map becomes empty after the operation.
(value: TValue, multiplicity: number)
| 60 | * Add a value to the PrefixMap. Returns true if the map becomes empty after the operation. |
| 61 | */ |
| 62 | addValue(value: TValue, multiplicity: number): boolean { |
| 63 | if (multiplicity === 0) return this.size === 0 |
| 64 | |
| 65 | const prefix = getPrefix<TValue, TPrefix>(value) |
| 66 | const valueMapOrSingleValue = this.get(prefix) |
| 67 | |
| 68 | if (isSingleValue(valueMapOrSingleValue)) { |
| 69 | const [currentValue, currentMultiplicity] = valueMapOrSingleValue |
| 70 | const currentPrefix = getPrefix<TValue, TPrefix>(currentValue) |
| 71 | |
| 72 | if (currentPrefix !== prefix) { |
| 73 | throw new Error(`Mismatching prefixes, this should never happen`) |
| 74 | } |
| 75 | |
| 76 | if (currentValue === value || hash(currentValue) === hash(value)) { |
| 77 | // Same value, update multiplicity |
| 78 | const newMultiplicity = currentMultiplicity + multiplicity |
| 79 | if (newMultiplicity === 0) { |
| 80 | this.delete(prefix) |
| 81 | } else { |
| 82 | this.set(prefix, [value, newMultiplicity]) |
| 83 | } |
| 84 | } else { |
| 85 | // Different suffixes, need to create ValueMap |
| 86 | const valueMap = new ValueMap<TValue>() |
| 87 | valueMap.set(hash(currentValue), valueMapOrSingleValue) |
| 88 | valueMap.set(hash(value), [value, multiplicity]) |
| 89 | this.set(prefix, valueMap) |
| 90 | } |
| 91 | } else if (valueMapOrSingleValue === undefined) { |
| 92 | // No existing value for this prefix |
| 93 | this.set(prefix, [value, multiplicity]) |
| 94 | } else { |
| 95 | // Existing ValueMap |
| 96 | const isEmpty = valueMapOrSingleValue.addValue(value, multiplicity) |
| 97 | if (isEmpty) { |
| 98 | this.delete(prefix) |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | return this.size === 0 |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | // Third level map type for the index, stores single values or value maps against a hash. |