diff --git a/sugar/lib/crdt.dart b/sugar/lib/crdt.dart index 5ee75257..18bcebe5 100644 --- a/sugar/lib/crdt.dart +++ b/sugar/lib/crdt.dart @@ -1,2 +1,2 @@ export 'src/crdt/string_index.dart'; -export 'src/crdt/string_index_set.dart'; +export 'src/crdt/string_indexed_list.dart'; diff --git a/sugar/lib/src/crdt/string_index_set.dart b/sugar/lib/src/crdt/string_index_set.dart deleted file mode 100644 index b888803e..00000000 --- a/sugar/lib/src/crdt/string_index_set.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'dart:collection'; - -import 'package:sugar/sugar.dart'; - -class StringIndexSet extends Iterable { - - /// Whether to strictly validate a string index's format. True by default. - final bool strict; - - final SplayTreeMap _map; - final HashMap _inverse; - final List _list; - final bool Function(E, E) _equals; - final int Function(E) _hash; - - StringIndexSet._( - this._map, - this._inverse, - this._list, - this._equals, - this._hash, { - required this.strict, - }); - - - void operator []= (Object index, E element) { - if (_inverse.containsKey(element)) { - return; - } - - switch (index) { - case final String index: - if (_map.firstValueAfter(index) case final after?) { - _list.insert(_list.indexWhere((e) => _equals(e, after)), element); - - } else { - _list.add(element); - } - - _map[index] = element; - _inverse[element] = index; - - // Different semantics between map and list - case final int index when index < _list.length: - final min = _inverse[_list.elementAtOrNull(index - 1)] ?? StringIndex.min; - final max = _inverse[_list.elementAtOrNull(index + 1)] ?? StringIndex.max; - final string = StringIndex.between(min: min, max: max, strict: strict); - _list.insert(index, element); - - } - } - - - @override - Iterator get iterator => _list.iterator; - - @override - E get first => _list.first; - - set first(E first) { - - } - -} diff --git a/sugar/lib/src/crdt/string_indexed_list.dart b/sugar/lib/src/crdt/string_indexed_list.dart new file mode 100644 index 00000000..490e1615 --- /dev/null +++ b/sugar/lib/src/crdt/string_indexed_list.dart @@ -0,0 +1,78 @@ +import 'dart:collection'; + +import 'package:sugar/sugar.dart'; + +class Sil extends Iterable { + + /// Whether to strictly validate a string index's format. True by default. + final bool strict; + + final SplayTreeMap _map; + final HashMap _inverse; + final List _list; + final bool Function(E, E) _equals; + final int Function(E) _hash; + + Sil._( + this._map, + this._inverse, + this._list, + this._equals, + this._hash, { + required this.strict, + }); + + + bool put(String index, E element) { + if (_inverse.containsKey(element)) { + return false; + } + + final old = _map[index]; + if (old == null) { + if (_map.firstValueAfter(index) case final after?) { + _list.insert(_list.indexWhere((e) => _equals(e, after)), element); + + } else { + _list.add(element); + } + + _map[index] = element; + _inverse[element] = index; + + } else { + _map[index] = element; + _inverse.remove(old); + _inverse[element] = index; + _list[_list.indexWhere((e) => _equals(e, old))] = element; + } + + return true; + } + + + int indexOf(E element) => _list.indexOf(element); + + String? stringIndexOf(E element) => _inverse[element]; + + + void operator []= (int index, E element) { + if (_inverse.containsKey(element)) { + return; + } + + final old = _list[index]; + final string = _inverse.remove(old)!; + + _map[string] = element; + _inverse[element] = string; + _list[index] = element; + } + + E operator [] (int index) => _list[index]; + + + @override + Iterator get iterator => _list.iterator; + +} diff --git a/sugar/test/src/crdt/string_index_test.dart b/sugar/test/src/crdt/string_index_test.dart index 395a0019..73e00eb0 100644 --- a/sugar/test/src/crdt/string_index_test.dart +++ b/sugar/test/src/crdt/string_index_test.dart @@ -1,6 +1,5 @@ import 'dart:math'; -import 'package:sugar/src/crdt/string_index.dart'; import 'package:sugar/sugar.dart'; import 'package:test/test.dart';