Skip to content

Commit b65cd56

Browse files
[MOD] XQuery: create compact sequence if size is known
1 parent de99eae commit b65cd56

File tree

5 files changed

+46
-31
lines changed

5 files changed

+46
-31
lines changed

basex-core/src/main/java/org/basex/query/value/ValueBuilder.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.basex.query.*;
44
import org.basex.query.expr.*;
5+
import org.basex.query.util.list.*;
56
import org.basex.query.value.item.*;
67
import org.basex.query.value.seq.*;
78
import org.basex.query.value.seq.tree.*;
@@ -52,24 +53,23 @@ public ValueBuilder(final QueryContext qc, final long capacity) {
5253
public ValueBuilder add(final Value value) {
5354
if(!value.isEmpty()) {
5455
qc.checkStop();
55-
final Value sngl = single;
56-
if(sngl != null) {
57-
single = null;
58-
if(capacity != Integer.MIN_VALUE) {
59-
sequence = isStr(sngl) && isStr(value) ? new StrSeqBuilder() :
60-
isAtm(sngl) && isAtm(value) ? new AtmSeqBuilder() :
61-
isInt(sngl) && isInt(value) ? new IntSeqBuilder() :
62-
isDbl(sngl) && isDbl(value) ? new DblSeqBuilder() :
63-
isBln(sngl) && isBln(value) ? new BlnSeqBuilder() : null;
56+
if(sequence == null) {
57+
final Value sngl = single;
58+
if(sngl == null) {
59+
single = value;
60+
return this;
6461
}
65-
if(sequence == null) sequence = new TreeSeqBuilder();
62+
single = null;
63+
sequence = capacity == Integer.MIN_VALUE ? new TreeSeqBuilder() :
64+
isStr(sngl) && isStr(value) ? new StrSeqBuilder() :
65+
isAtm(sngl) && isAtm(value) ? new AtmSeqBuilder() :
66+
isInt(sngl) && isInt(value) ? new IntSeqBuilder() :
67+
isDbl(sngl) && isDbl(value) ? new DblSeqBuilder() :
68+
isBln(sngl) && isBln(value) ? new BlnSeqBuilder() :
69+
new ItemSeqBuilder();
6670
add(sngl);
6771
}
68-
if(sequence != null) {
69-
sequence = sequence.add(value, qc);
70-
} else {
71-
single = value;
72-
}
72+
sequence = sequence.add(value, qc);
7373
}
7474
return this;
7575
}
@@ -260,4 +260,21 @@ public Value value(final Type type) {
260260
return BlnSeq.get(values.finish());
261261
}
262262
}
263+
264+
/** Item sequence builder. */
265+
final class ItemSeqBuilder implements SeqBuilder {
266+
/** Items. */
267+
private final ItemList items = new ItemList(capacity);
268+
269+
@Override
270+
public SeqBuilder add(final Item item) {
271+
items.add(item);
272+
return this;
273+
}
274+
275+
@Override
276+
public Value value(final Type type) {
277+
return items.value(type);
278+
}
279+
}
263280
}

basex-core/src/main/java/org/basex/query/value/array/ArrayBuilder.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,18 @@ public ArrayBuilder(final QueryContext qc, final long capacity) {
5353
* @return reference to this builder for convenience
5454
*/
5555
public ArrayBuilder add(final Value value) {
56-
final Value sngl = single;
57-
if(sngl != null) {
56+
if(array == null) {
57+
final Value sngl = single;
58+
if(sngl == null) {
59+
single = value;
60+
return this;
61+
}
5862
single = null;
59-
array = capacity != Integer.MIN_VALUE && sngl.size() == 1 && value.size() == 1 ?
60-
new ItemArrayBuilder(qc, capacity) : new TreeArrayBuilder();
63+
array = capacity == Integer.MIN_VALUE || sngl.size() != 1 || value.size() != 1 ?
64+
new TreeArrayBuilder() : new ItemArrayBuilder(qc, capacity);
6165
add(sngl);
6266
}
63-
if(array != null) {
64-
array = array.add(value);
65-
} else {
66-
single = value;
67-
}
67+
array = array.add(value);
6868
return this;
6969
}
7070

basex-core/src/test/java/org/basex/query/ast/RewritingsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ public final class RewritingsTest extends SandboxTest {
10161016
check("(1, 2) coerce to xs:double+", "1\n2",
10171017
empty(TypeCheck.class), root(DblSeq.class), count(Dbl.class, 2));
10181018
check("(-128, 127) coerce to xs:byte+", "-128\n127",
1019-
empty(TypeCheck.class), root(SmallSeq.class), count(Itr.class, 2));
1019+
empty(TypeCheck.class), root(ItemSeq.class), count(Itr.class, 2));
10201020

10211021
error("<a/> coerce to empty-sequence()", INVTYPE_X);
10221022
error("(1, 128) coerce to xs:byte+", FUNCCAST_X_X_X);
@@ -2121,7 +2121,7 @@ private static String gh1852(final String query) {
21212121

21222122
check("for $a in (1, 2) group by $a return $a", "1\n2", root(RangeSeq.class));
21232123
check("for $a in (1, 3) group by $a return $a", "1\n3", root(IntSeq.class));
2124-
check("for $a in (1, 'a', 1) group by $a return $a", "1\na", root(SmallSeq.class));
2124+
check("for $a in (1, 'a', 1) group by $a return $a", "1\na", root(ItemSeq.class));
21252125

21262126
check("for $p in (1 to 2)[. >= 0] group by $q := string($p) return $q",
21272127
"1\n2", root(DISTINCT_VALUES), exists(DualMap.class));

basex-core/src/test/java/org/basex/query/expr/MixedTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import org.basex.query.value.item.*;
1414
import org.basex.query.value.map.*;
1515
import org.basex.query.value.seq.*;
16-
import org.basex.query.value.seq.tree.*;
1716
import org.junit.jupiter.api.*;
1817
import org.junit.jupiter.api.Test;
1918

@@ -471,10 +470,10 @@ public final class MixedTest extends SandboxTest {
471470
/** Tests the data structure before and after shrinking. */
472471
@Test public void shrink() {
473472
test("('x', 1 to 3) => remove(1)",
474-
new TypeInfo(SmallSeq.class, "xs:anyAtomicType+", 3),
473+
new TypeInfo(SubSeq.class, "xs:anyAtomicType+", 3),
475474
new TypeInfo(RangeSeq.class, "xs:integer+", 3));
476475
test("('x', 1 to 100) => remove(1)",
477-
new TypeInfo(BigSeq.class, "xs:anyAtomicType+", 100),
476+
new TypeInfo(SubSeq.class, "xs:anyAtomicType+", 100),
478477
new TypeInfo(RangeSeq.class, "xs:integer+", 100));
479478

480479
test("map:build(1 to 3) => map:remove(1)",

basex-core/src/test/java/org/basex/query/expr/SimpleMapTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import org.basex.query.expr.constr.*;
88
import org.basex.query.value.item.*;
99
import org.basex.query.value.seq.*;
10-
import org.basex.query.value.seq.tree.*;
1110
import org.basex.query.var.*;
1211
import org.junit.jupiter.api.*;
1312

@@ -82,7 +81,7 @@ public final class SimpleMapTest extends SandboxTest {
8281

8382
/** Inline simple expressions into next operand. */
8483
@Test public void inline() {
85-
check("'1' ! (., number())", "1\n1", root(SmallSeq.class));
84+
check("'1' ! (., number())", "1\n1", root(ItemSeq.class));
8685
check("let $a := document { <a/> } return $a ! (., /)", "<a/>\n<a/>", empty(VarRef.class));
8786
check("let $d := document{} return $d ! /", "", root(CDoc.class));
8887
check("{ 1: 2 } ! ?*", 2, root(Itr.class));

0 commit comments

Comments
 (0)