syndicate-nim/src/syndicate/bags.nim

39 lines
989 B
Nim

# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
## An unordered association of items to counts.
## An item count may be negative, unlike CountTable.
import tables
type
ChangeDescription* = enum
cdPresentToAbsent,
cdAbsentToAbsent,
cdAbsentToPresent,
cdPresentToPresent
Bag*[T] = Table[T, int]
proc change(count: var int; delta: int; clamp: bool): ChangeDescription =
var
oldCount = count
newCount = oldCount + delta
if clamp:
newCount = max(0, newCount)
if newCount == 0:
result =
if oldCount == 0: cdAbsentToAbsent
else: cdPresentToAbsent
else:
result =
if oldCount == 0: cdAbsentToPresent
else: cdPresentToPresent
count = newCount
proc change*[T](bag: var Bag[T]; key: T; delta: int; clamp = false): ChangeDescription =
assert(delta != 0)
result = change(bag.mGetOrPut(key, 0), delta, clamp)
if result in {cdAbsentToAbsent, cdPresentToAbsent}:
bag.del(key)