TernaryTreap

This library defines 2 Multimaps and a Set implemented as self balancing compact ternary trees allowing fast, memory efficient prefix and near neighbour searching over a set of String keys

  • TTMultiMapSet - Keys map to Set of Values
  • TTMultiMapList - Keys map to Sequence of Values
  • TTSet - A Set of Strings

Balancing is achieved via Treap algorithm where each node is assigned a random priority and tree rotation used to maintain heap ordering.

Usage

Use as a generic multimap of arbitrary type. Key->Values relations are stored as either Set or List as below.

final ttMultimapList = ternarytreap.TTMultiMapList<int>()
  ..add('zebra')
  ..addValues('zebra', [])
  ..add('zebra', 23)
  ..addValues('cat', [1, 2])
  ..addValues('canary', [3, 4])
  ..addValues('dog', [5, 6, 7, 9])
  ..addValues('cow', [4])
  ..addValues('donkey', [7, 5, 1])
  ..addValues('donkey', [6, 8, 3])
  ..add('goat', 7)
  ..add('pig', 3)
  ..addValues('horse', [9, 5, 8])
  ..add('rabbit')
  ..addValues('rat', [2, 3])
  ..add('sheep', 7)
  ..addValues('ape', [5, 6, 7])
  ..add('zonkey') // Yes it's a thing!
  ..add('dingo', 5)
  ..addValues('kangaroo', [4, 5, 7])
  ..add('chicken')
  ..add('hawk')
  ..add('crocodile', 5)
  ..addValues('cow', [3])
  ..addValues('zebra', [23, 24, 24, 25]);

Entries with keys starting with 'z'

print(ttMultimapList.keysByPrefix('z'));
print(ttMultimapList.entriesByKeyPrefix('z'));
print(ttMultimapList.valuesByKeyPrefix('z'));
(zebra, zonkey)
(MapEntry(zebra: [23, 23, 24, 24, 25]), MapEntry(zonkey: []))
(23, 23, 24, 24, 25)

Same data using Set for value storage. Repeated values are removed.

final ttMultimapSet =
         ternarytreap.TTMultiMapSet<int>.from(ttMultimapList);

Entries with keys starting with 'z' with values.

print(ttMultimapSet.entriesByKeyPrefix('z'));
(MapEntry(zebra: {23, 24, 25}), MapEntry(zonkey: {}))

Near neighbour searching

TTMultiMap supports near neighbour searching. Keys starting with 'cow' and maxPrefixEditDistance of 2. i.e.: cow, chicken, crocodile, canary, cat, dog, donkey, goat, hawk, horse, zonkey

print(ttMultimapSet.keysByPrefix('cow', maxPrefixEditDistance: 2).join(', '));
cow, chicken, crocodile, canary, cat, dog, donkey, goat, hawk, horse, zonkey

Case sensitivity and other key transformations

Use key mappings to specify key transforms during all operations.

final ttMultiMap = ternarytreap.TTMultiMapSet<String>(ternarytreap.lowercase)
  ..addKeys(['TeStInG', 'Cat', 'cAt', 'testinG', 'DOG', 'dog']);
print(ttMultiMap.keys);
(cat, dog, testing)

Depending on the KeyMapping this may result in 1 to many relationships between input string and key.

For example case insensitivity can be achieved by applying a lowercase mapping to all keys. If original strings are required than these must be stored as values.

final keyValue = ternarytreap.TTMultiMapSet<String>(ternarytreap.lowercase)
  ..addKeyValues(['TeStInG', 'Cat', 'cAt', 'testinG', 'DOG', 'dog']);
print(keyValue.entries);
print(keyValue.valuesByKeyPrefix('CA'));
(MapEntry(cat: {Cat, cAt}), MapEntry(dog: {DOG, dog}), MapEntry(testing: {TeStInG, testinG}))
(Cat, cAt)

Features and bugs

Please file feature requests and bugs at the issue tracker.

Libraries

ternarytreap
This library defines 2 Multimaps and a Set implemented as self balancing compact ternary trees allowing fast, memory efficient prefix and near neighbour searching over a set of String keys