Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[refactor] merge duplicates: combine, reject
Reject by counting expected size of merge. Combine uses a merge-with-combine fn from the underlying collection code.
Passes an initial set of tests. There’s some code we have written for completeness (MapType merge with combiner operator) which doesn’t seem to get called. Need to investigate/test further.
  • Loading branch information
alanpaxton authored and adamretter committed Feb 5, 2023
commit 3e37402d0fe2f01a4ac3e7f7c2eb2426ddaef598
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,4 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
return map.get((AtomicValue) args[0].itemAt(0));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,43 @@ public AbstractMapType merge(final Iterable<AbstractMapType> others, final Binar
return new MapType(context, newMap.forked(), prevType);
}

@Override
public AbstractMapType merge(final Iterable<AbstractMapType> others, final BinaryOperator<Sequence> mergeFn) {

// create a transient map
IMap<AtomicValue, Sequence> newMap = map.linear();

int prevType = keyType;
for (final AbstractMapType other: others) {
if (other instanceof MapType) {
// MapType - optimise merge
final MapType otherMap = (MapType) other;
newMap = newMap.merge(otherMap.map, mergeFn);

if (prevType != otherMap.keyType) {
prevType = MIXED_KEY_TYPES;
}
} else {
// non MapType
for (final IEntry<AtomicValue, Sequence> entry : other) {
final AtomicValue key = entry.key();
final Optional<Sequence> headEntry = newMap.get(key);
if (headEntry.isPresent()) {
newMap = newMap.put(key, mergeFn.apply(headEntry.get(), entry.value()));
} else {
newMap = newMap.put(key, entry.value());
}
if (prevType != key.getType()) {
prevType = MIXED_KEY_TYPES;
}
}
}
}

// return an immutable map
return new MapType(context, newMap.forked(), prevType);
}

public void add(final AtomicValue key, final Sequence value) {
setKeyType(key.getType());
map = map.put(key, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public AbstractMapType merge(final Iterable<AbstractMapType> others, final Binar
}
}

@Override
public AbstractMapType merge(final Iterable<AbstractMapType> others, final BinaryOperator<Sequence> mergeFn) {
final MapType map = new MapType(context, collator, key, value);
return map.merge(others, mergeFn);
}

@Override
public AbstractMapType put(final AtomicValue key, final Sequence value) {
final IMap<AtomicValue, Sequence> map = newLinearMap(collator);
Expand Down