/** * Optimizes descendant-or-self steps and static types. * * @param ctx query context */ void optSteps(final QueryContext ctx) { boolean opt = false; Expr[] st = steps; for (int l = 1; l < st.length; ++l) { if (!(st[l - 1] instanceof Step && st[l] instanceof Step)) continue; final Step prev = (Step) st[l - 1]; final Step curr = (Step) st[l]; if (!prev.simple(DESCORSELF, false)) continue; if (curr.axis == CHILD && !curr.has(Flag.FCS)) { // descendant-or-self::node()/child::X -> descendant::X final int sl = st.length; final Expr[] tmp = new Expr[sl - 1]; System.arraycopy(st, 0, tmp, 0, l - 1); System.arraycopy(st, l, tmp, l - 1, sl - l); st = tmp; curr.axis = DESC; opt = true; } else if (curr.axis == ATTR && !curr.has(Flag.FCS)) { // descendant-or-self::node()/@X -> descendant-or-self::*/@X prev.test = new NameTest(false); opt = true; } } if (opt) ctx.compInfo(OPTDESC); // set atomic type for single attribute steps to speedup predicate tests if (root == null && st.length == 1 && st[0] instanceof Step) { final Step curr = (Step) st[0]; if (curr.axis == ATTR && curr.test.mode == Mode.STD) curr.type = SeqType.NOD_ZO; } steps = st; }
@Override public Item item(final QueryContext qc, final InputInfo ii) throws QueryException { final B64 b64 = toB64(exprs[0], qc, true); long by = toLong(exprs[1], qc); if (b64 == null) return null; if (by == 0) return b64; byte[] bytes = b64.binary(info); final int bl = bytes.length; byte[] tmp = new byte[bl]; int r = 0; if (by > 7) { tmp = new BigInteger(bytes).shiftLeft((int) by).toByteArray(); if (tmp.length != bl) { bytes = tmp; tmp = new byte[bl]; System.arraycopy(bytes, bytes.length - bl, tmp, 0, bl); } } else if (by > 0) { for (int i = bl - 1; i >= 0; i--) { final byte b = bytes[i]; tmp[i] = (byte) (b << by | r); r = b >>> 32 - by; } } else if (by > -8) { by = -by; for (int i = 0; i < bl; i++) { final int b = bytes[i] & 0xFF; tmp[i] = (byte) (b >>> by | r); r = b << 32 - by; } } else { by = -by; BigInteger bi = new BigInteger(bytes); if (bi.signum() >= 0) { bi = bi.shiftRight((int) by); } else { final BigInteger o = BigInteger.ONE.shiftLeft(bl * 8 + 1); final BigInteger m = o.subtract(BigInteger.ONE).shiftRight((int) by + 1); bi = bi.subtract(o).shiftRight((int) by).and(m); } tmp = bi.toByteArray(); final int tl = tmp.length; if (tl != bl) { bytes = tmp; tmp = new byte[bl]; System.arraycopy(bytes, 0, tmp, bl - tl, tl); } } return new B64(tmp); }
/** * Gathers all declared variables. * * @param gs grouping specs * @param vs non-grouping variables * @return declared variables */ private static Var[] vars(final Spec[] gs, final Var[] vs) { final int gl = gs.length, vl = vs.length; final Var[] res = new Var[gl + vl]; for (int g = 0; g < gl; g++) res[g] = gs[g].var; System.arraycopy(vs, 0, res, gl, vl); return res; }
/** * Constructor. * * @param specs grouping specs * @param pre references to pre-grouping variables * @param post post-grouping variables * @param info input info */ public GroupBy(final Spec[] specs, final VarRef[] pre, final Var[] post, final InputInfo info) { super(info, vars(specs, post)); this.specs = specs; this.post = post; preExpr = new Expr[pre.length]; System.arraycopy(pre, 0, preExpr, 0, pre.length); int n = 0; for (final Spec spec : specs) if (!spec.occluded) n++; nonOcc = n; }
/** * Sets the output text. * * @param out cached output */ public void setText(final ArrayOutput out) { final byte[] buf = out.buffer(); final int size = (int) out.size(); final byte[] chop = token(DOTS); if (out.finished() && size >= chop.length) { System.arraycopy(chop, 0, buf, size - chop.length, chop.length); } text.setText(buf, size); header.setText((out.finished() ? CHOPPED : "") + RESULT); home.setEnabled(gui.context.data() != null); }
/** * Copies the children array. This is faster than {@code kids.clone()} according to <a * href="http://www.javaspecialists.eu/archive/Issue124.html">Heinz M. Kabutz</a>. * * @return copy of the child array */ TrieNode[] copyKids() { final TrieNode[] copy = new TrieNode[KIDS]; System.arraycopy(kids, 0, copy, 0, KIDS); return copy; }