Skip to content

Commit 8982ea1

Browse files
authored
Merge branch 'master' into next
2 parents 749b8fc + 753e669 commit 8982ea1

3 files changed

Lines changed: 41 additions & 4 deletions

File tree

src/main/java/org/rumbledb/items/ItemFactory.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ public Item createMapItemRemovingKeys(
357357
Item original,
358358
List<Item> keysToRemove
359359
) {
360+
original = rebaseDeepMapOverlay(original);
360361
return new MapWithRemovedEntryItem(original, keysToRemove);
361362
}
362363

@@ -365,9 +366,32 @@ public Item createMapItemAddingKey(
365366
Item keyToAdd,
366367
List<Item> valueToAdd
367368
) {
369+
original = rebaseDeepMapOverlay(original);
368370
return new MapWithAdditionalEntryItem(original, keyToAdd, valueToAdd);
369371
}
370372

373+
static int getMapOverlayChainLength(Item item) {
374+
if (item instanceof MapWithAdditionalEntryItem additionalEntry) {
375+
return additionalEntry.getOverlayChainLength();
376+
}
377+
if (item instanceof MapWithRemovedEntryItem removedEntry) {
378+
return removedEntry.getOverlayChainLength();
379+
}
380+
return 0;
381+
}
382+
383+
private Item rebaseDeepMapOverlay(Item original) {
384+
if (getMapOverlayChainLength(original) < MapWithAdditionalEntryItem.MAX_OVERLAY_CHAIN_LENGTH) {
385+
return original;
386+
}
387+
return createMapItem(
388+
original.getItemKeys(),
389+
original.getSequenceValues(),
390+
ExceptionMetadata.EMPTY_METADATA,
391+
false
392+
);
393+
}
394+
371395
public Item createMapItem(
372396
List<Item> keys,
373397
List<List<Item>> values,

src/main/java/org/rumbledb/items/MapWithAdditionalEntryItem.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,27 @@ public class MapWithAdditionalEntryItem extends AbstractMapItem {
3838
@Serial
3939
private static final long serialVersionUID = 1L;
4040

41+
static final int MAX_OVERLAY_CHAIN_LENGTH = 32;
42+
4143
/**
4244
* This is an optimization version of maps when there is exactly one key-value pair.
4345
*/
4446
private final Item original;
4547
private final Item additionalKey;
4648
private final List<Item> additionalValue;
49+
private final int size;
50+
private final int chainLength;
4751

4852
public MapWithAdditionalEntryItem(Item original, Item additionalKey, List<Item> additionalValue) {
4953
this.original = original;
5054
this.additionalKey = additionalKey;
5155
this.additionalValue = additionalValue;
56+
this.size = original.getSize() + (original.hasKey(additionalKey) ? 0 : 1);
57+
this.chainLength = ItemFactory.getMapOverlayChainLength(original) + 1;
58+
}
59+
60+
int getOverlayChainLength() {
61+
return this.chainLength;
5262
}
5363

5464
@Override
@@ -114,10 +124,7 @@ public List<Item> getItemKeys() {
114124

115125
@Override
116126
public int getSize() {
117-
if (this.original.hasKey(this.additionalKey)) {
118-
return this.original.getSize();
119-
}
120-
return this.original.getSize() + 1;
127+
return this.size;
121128
}
122129

123130
@Override

src/main/java/org/rumbledb/items/MapWithRemovedEntryItem.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ public class MapWithRemovedEntryItem extends AbstractMapItem {
4646
*/
4747
private final Item original;
4848
private final Set<Item> removedKeys;
49+
private final int chainLength;
4950

5051
public MapWithRemovedEntryItem(Item original, List<Item> removedKeys) {
5152
this.original = original;
53+
this.chainLength = ItemFactory.getMapOverlayChainLength(original) + 1;
5254
this.removedKeys = new HashSet<>();
5355
for (Item key : removedKeys) {
5456
if (this.original.isObject()) {
@@ -66,6 +68,10 @@ public MapWithRemovedEntryItem(Item original, List<Item> removedKeys) {
6668
}
6769
}
6870

71+
int getOverlayChainLength() {
72+
return this.chainLength;
73+
}
74+
6975
@Override
7076
public Item copy(boolean mutable) {
7177
if (mutable) {

0 commit comments

Comments
 (0)