Skip to content

Commit

Permalink
Implement persistent part of the Map API for ListMap
Browse files Browse the repository at this point in the history
  • Loading branch information
Gene Gleyzer committed Jun 22, 2022
1 parent 88d3444 commit 1eb4c78
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 29 deletions.
4 changes: 3 additions & 1 deletion doc/todo-list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
72 changes: 62 additions & 10 deletions lib_ecstasy/src/main/x/ecstasy/collections/ListMap.x
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -208,22 +210,56 @@ 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
ListMap remove(Key key)
{
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;
Expand All @@ -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);
}
}
}

Expand All @@ -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;
Expand Down
11 changes: 7 additions & 4 deletions lib_ecstasy/src/main/x/ecstasy/collections/ListMapIndex.x
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -459,4 +462,4 @@ mixin ListMapIndex<Key extends Hashable, Value>
}
return indexes - 1;
}
}
}
14 changes: 0 additions & 14 deletions manualTests/src/main/x/TestSimple.x
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 1eb4c78

Please sign in to comment.