From 1eb4c78a2e75b198a71f6362476be41ba2b0d52a Mon Sep 17 00:00:00 2001 From: Gene Gleyzer <gene@xqiz.it> Date: Wed, 22 Jun 2022 14:14:44 -0400 Subject: [PATCH] Implement persistent part of the Map API for ListMap --- doc/todo-list.txt | 4 +- .../src/main/x/ecstasy/collections/ListMap.x | 72 ++++++++++++++++--- .../main/x/ecstasy/collections/ListMapIndex.x | 11 +-- manualTests/src/main/x/TestSimple.x | 14 ---- 4 files changed, 72 insertions(+), 29 deletions(-) diff --git a/doc/todo-list.txt b/doc/todo-list.txt index 893a5cf597..b3b6bab8b7 100644 --- a/doc/todo-list.txt +++ b/doc/todo-list.txt @@ -3,7 +3,9 @@ const Test(HashMap<Int, String> map) - json serialization DOESN'T WORK - need to make _native module non-discoverable (and services for container -1) - see TestSimple.x on the shelve + see TestSimple.x on the shelf + +- need to implement "persistent" mutators for HasherMap - the XTC compiler disregards "resources" changes if nothing else changed and "-force" option is not specified diff --git a/lib_ecstasy/src/main/x/ecstasy/collections/ListMap.x b/lib_ecstasy/src/main/x/ecstasy/collections/ListMap.x index c4113dc26f..3172666755 100644 --- a/lib_ecstasy/src/main/x/ecstasy/collections/ListMap.x +++ b/lib_ecstasy/src/main/x/ecstasy/collections/ListMap.x @@ -43,8 +43,10 @@ class ListMap<Key, Value> */ construct(Key[] keys, Value[] vals) { - this.keyArray = keys; - this.valArray = vals; + this.keyArray = keys.mutability == Persistent || keys.mutability == Constant + ? keys : keys.freeze(inPlace=False); + this.valArray = vals.mutability == Persistent || vals.mutability == Constant + ? vals : vals.freeze(inPlace=False); this.inPlace = False; // TODO various checks, and do we need to copy the array(s) if they aren't immutable? @@ -208,14 +210,39 @@ class ListMap<Key, Value> { if (Int index := indexOf(key)) { + verifyInPlace(); valArray[index] = value; + return this; } - else + + if (inPlace) { appendEntry(key, value); + return this; } - return this; + // persistent + Key[] keys = keyArray.add(key); + Value[] vals = valArray.add(value); + return new ListMap(keys, vals); + } + + @Override + ListMap putAll(Map<Key, Value> that) + { + if (inPlace) + { + for ((Key key, Value value) : that) + { + put(key, value); + } + return this; + } + + // persistent + Key[] keys = keyArray.addAll(that.keys.toArray()); + Value[] vals = valArray.addAll(that.values.toArray()); + return new ListMap(keys, vals); } @Override @@ -223,7 +250,16 @@ class ListMap<Key, Value> { if (Int index := indexOf(key)) { - deleteEntryAt(index); + if (inPlace) + { + deleteEntryAt(index); + } + else // persistent + { + Key[] keys = keyArray.delete(index); + Value[] vals = valArray.delete(index); + return new ListMap(keys, vals); + } } return this; @@ -236,8 +272,17 @@ class ListMap<Key, Value> { if (valArray[index] == value) { - deleteEntryAt(index); - return True, this; + if (inPlace) + { + deleteEntryAt(index); + return True, this; + } + else // persistent + { + Key[] keys = keyArray.delete(index); + Value[] vals = valArray.delete(index); + return True, new ListMap(keys, vals); + } } } @@ -250,9 +295,16 @@ class ListMap<Key, Value> Int count = size; if (count > 0) { - keyArray.clear(); - valArray.clear(); - deletes += count; + if (inPlace) + { + keyArray.clear(); + valArray.clear(); + deletes += count; + } + else // persistent + { + return new ListMap([], []); + } } return this; diff --git a/lib_ecstasy/src/main/x/ecstasy/collections/ListMapIndex.x b/lib_ecstasy/src/main/x/ecstasy/collections/ListMapIndex.x index e1c88ffe18..a24ff6510c 100644 --- a/lib_ecstasy/src/main/x/ecstasy/collections/ListMapIndex.x +++ b/lib_ecstasy/src/main/x/ecstasy/collections/ListMapIndex.x @@ -48,7 +48,7 @@ mixin ListMapIndex<Key extends Hashable, Value> Bucket[]? buckets = this.buckets; if (buckets == Null) { - if (size > MINSIZE) + if (size > MINSIZE && inPlace) { buildIndex(); buckets = this.buckets; @@ -171,14 +171,17 @@ mixin ListMapIndex<Key extends Hashable, Value> @Override ListMapIndex clear() { - buckets = Null; + if (inPlace) + { + buckets = Null; + } return super(); } @Override immutable ListMapIndex makeImmutable() { - if (buckets == Null && size > MINSIZE) + if (buckets == Null && size > MINSIZE && inPlace) { buildIndex(); } @@ -459,4 +462,4 @@ mixin ListMapIndex<Key extends Hashable, Value> } return indexes - 1; } - } + } \ No newline at end of file diff --git a/manualTests/src/main/x/TestSimple.x b/manualTests/src/main/x/TestSimple.x index 7ce4c031c3..10138ebe64 100644 --- a/manualTests/src/main/x/TestSimple.x +++ b/manualTests/src/main/x/TestSimple.x @@ -21,18 +21,4 @@ module TestSimple // map = map.put(2, "b"); // testSer(schema, "map", new Test(map)); } - - private <Ser> void testSer(Schema schema, String name, Ser val) - { - StringBuffer buf = new StringBuffer(); - schema.createObjectOutput(buf).write(val); - - String s = buf.toString(); - console.println($"JSON {name} written out={s}"); - - Ser val2 = schema.createObjectInput(new CharArrayReader(s)).read<Ser>(); - console.println($"read {name} back in={val2}"); - } - - const Test(Map<Int, String> map); } \ No newline at end of file