예제 #1
0
파일: IdPreMap.java 프로젝트: fpapai/basex
 /**
  * Adds a record to the table and the ID index.
  *
  * @param i index in the table where the record should be inserted
  * @param pre pre value
  * @param fid first ID value
  * @param nid last ID value
  * @param inc increment value
  * @param oid original ID value
  */
 private void add(
     final int i, final int pre, final int fid, final int nid, final int inc, final int oid) {
   if (rows == pres.length) {
     final int s = Array.newSize(rows);
     pres = Arrays.copyOf(pres, s);
     fids = Arrays.copyOf(fids, s);
     nids = Arrays.copyOf(nids, s);
     incs = Arrays.copyOf(incs, s);
     oids = Arrays.copyOf(oids, s);
   }
   if (i < rows) {
     final int destPos = i + 1;
     final int length = rows - i;
     System.arraycopy(pres, i, pres, destPos, length);
     System.arraycopy(fids, i, fids, destPos, length);
     System.arraycopy(nids, i, nids, destPos, length);
     System.arraycopy(incs, i, incs, destPos, length);
     System.arraycopy(oids, i, oids, destPos, length);
   }
   pres[i] = pre;
   fids[i] = fid;
   nids[i] = nid;
   incs[i] = inc;
   oids[i] = oid;
   ++rows;
 }
예제 #2
0
파일: Path.java 프로젝트: nikhi/basex
  /**
   * 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;
  }
예제 #3
0
  /**
   * Adds a single object at the specified position.
   *
   * @param obj object to insert
   * @param o index
   */
  void add(final ViewLayout obj, final int o) {
    final int n = comp.length;
    final ViewLayout[] tmp = new ViewLayout[n + 1];

    System.arraycopy(comp, 0, tmp, 0, o);
    System.arraycopy(comp, o, tmp, o + 1, n - o);
    comp = tmp;
    comp[o] = obj;
  }
예제 #4
0
파일: IdPreMap.java 프로젝트: fpapai/basex
 /**
  * Removes a records from the table and the ID index.
  *
  * @param s start index of records in the table (inclusive)
  * @param e end index of records in the table (inclusive)
  */
 private void remove(final int s, final int e) {
   if (s <= e) {
     final int last = e + 1;
     final int length = rows - last;
     System.arraycopy(pres, last, pres, s, length);
     System.arraycopy(fids, last, fids, s, length);
     System.arraycopy(nids, last, nids, s, length);
     System.arraycopy(incs, last, incs, s, length);
     System.arraycopy(oids, last, oids, s, length);
     rows -= last - s;
   }
 }
예제 #5
0
파일: BinShift.java 프로젝트: fpapai/basex
  @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);
  }
예제 #6
0
파일: NSNode.java 프로젝트: phspaelti/basex
  /**
   * Recursively deletes the specified namespace URI reference.
   *
   * @param uri namespace URI reference
   */
  void delete(final int uri) {
    for (int c = 0; c < sz; ++c) children[c].delete(uri);

    final int vl = values.length;
    for (int v = 0; v < vl; v += 2) {
      if (values[v + 1] != uri) continue;
      final int[] vals = new int[vl - 2];
      System.arraycopy(values, 0, vals, 0, v);
      System.arraycopy(values, v + 2, vals, v, vl - v - 2);
      values = vals;
      break;
    }
  }
예제 #7
0
 /**
  * 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;
 }
예제 #8
0
 /**
  * Fill the current buffer with bytes from the specified array from the specified offset.
  *
  * @param s source array
  * @param o offset from the beginning of the array
  * @return number of written bytes
  */
 private int write(final byte[] s, final int o) {
   final Buffer bf = bm.current();
   final int len = Math.min(IO.BLOCKSIZE, s.length - o);
   System.arraycopy(s, o, bf.data, 0, len);
   bf.dirty = true;
   return len;
 }
예제 #9
0
 /**
  * Writes a log message.
  *
  * @param str strings to be written
  * @param time add performance info
  */
 public void log(final boolean time, final Object... str) {
   final Object[] obj = new Object[str.length + (time ? 2 : 1)];
   obj[0] = remote();
   System.arraycopy(str, 0, obj, 1, str.length);
   if (time) obj[obj.length - 1] = perf.toString();
   context.log.write(obj);
 }
예제 #10
0
 @Override
 protected void copy(final byte[] entries, final int pre, final int last) {
   for (int o = 0, i = pre; i < last; ++i, o += IO.NODESIZE) {
     final int off = cursor(i);
     final Buffer bf = bm.current();
     System.arraycopy(entries, o, bf.data, off, IO.NODESIZE);
     bf.dirty = true;
   }
 }
예제 #11
0
 /**
  * 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;
 }
예제 #12
0
파일: TextView.java 프로젝트: dirkk/basex
 /**
  * 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);
 }
예제 #13
0
파일: NSNode.java 프로젝트: phspaelti/basex
  /**
   * Adds the specified node into the child array, which is sorted by pre values.
   *
   * @param node child node
   */
  void add(final NSNode node) {
    if (sz == children.length) children = Array.copy(children, new NSNode[Array.newSize(sz)]);

    // find inserting position
    int s = find(node.pr);
    if (s < 0 || node.pr != children[s].pr) s++;

    System.arraycopy(children, s, children, s + 1, sz++ - s);
    children[s] = node;
    node.parent = this;
  }
예제 #14
0
  /**
   * Indexes the specified name and its kind.
   *
   * @param nm name id
   * @param knd node kind
   * @param value value
   * @param meta meta data
   * @return node reference
   */
  PathNode index(final int nm, final byte knd, final byte[] value, final MetaData meta) {
    for (final PathNode c : children) {
      if (c.kind == knd && c.name == nm) {
        if (value != null) c.stats.add(value, meta);
        c.stats.count++;
        return c;
      }
    }

    final PathNode node = new PathNode(nm, knd, this);
    if (value != null) node.stats.add(value, meta);

    final int cs = children.length;
    final PathNode[] nodes = new PathNode[cs + 1];
    System.arraycopy(children, 0, nodes, 0, cs);
    nodes[cs] = node;
    children = nodes;
    return node;
  }
예제 #15
0
  /**
   * Adds values to the index.
   *
   * @param key key to be indexed
   * @param vals sorted values
   */
  void add(final byte[] key, final int... vals) {
    // token index: add values. otherwise, reference existing values
    final int id = type == IndexType.TOKEN ? values.put(key) : values.id(key), vl = vals.length;
    // updatable index: if required, resize existing arrays
    while (idsList.size() < id + 1) idsList.add(null);
    if (lenList.size() < id + 1) lenList.set(id, 0);

    final int len = lenList.get(id), size = len + vl;
    int[] ids = idsList.get(id);
    if (ids == null) {
      ids = vals;
    } else {
      if (ids.length < size) ids = Arrays.copyOf(ids, Array.newSize(size));
      System.arraycopy(vals, 0, ids, len, vl);
      if (ids[len - 1] > vals[0]) {
        if (reorder == null) reorder = new BoolList(values.size());
        reorder.set(id, true);
      }
    }
    idsList.set(id, ids);
    lenList.set(id, size);
  }
예제 #16
0
파일: NSNode.java 프로젝트: phspaelti/basex
  /**
   * Deletes nodes in the specified range (p .. p + sz - 1) and updates the following pre values
   *
   * @param pre pre value
   * @param size number of nodes to be deleted, or actually the size of the pre value which is to be
   *     deleted
   */
  void delete(final int pre, final int size) {
    // find the pre value which must be deleted
    int s = find(pre);
    /* if the node is not directly contained as a child, either start at array
     * index 0 or proceed with the next node in the child array to search for
     * descendants of pre
     */
    if (s == -1 || children[s].pr != pre) ++s;
    // first pre value which is not deleted
    final int upper = pre + size;
    // number of nodes to be deleted
    int num = 0;
    // determine number of nodes to be deleted
    for (int i = s; i < sz && children[i].pr < upper; ++i, ++num) ;
    // new size of child array
    sz -= num;

    // if all nodes are deleted, just create an empty array
    if (sz == 0) children = new NSNode[0];

    // otherwise remove nodes from the child array
    else if (num > 0) System.arraycopy(children, s + num, children, s, sz - s);
  }
예제 #17
0
 /**
  * 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;
 }
예제 #18
0
 /**
  * Convenience method for copying blocks.
  *
  * @param s source array
  * @param sp source position
  * @param d destination array
  * @param dp destination position
  * @param l source length
  */
 private void copy(final byte[] s, final int sp, final byte[] d, final int dp, final int l) {
   System.arraycopy(s, sp << IO.NODEPOWER, d, dp << IO.NODEPOWER, l << IO.NODEPOWER);
   bm.current().dirty = true;
 }
예제 #19
0
  @Override
  public void insert(final int pre, final byte[] entries) {
    final int nnew = entries.length;
    if (nnew == 0) return;
    dirty();

    // number of records to be inserted
    final int nr = nnew >>> IO.NODEPOWER;

    int split = 0;
    if (used == 0) {
      // special case: insert new data into first block if database is empty
      readPage(0);
      usedPages.set(0);
      ++used;
    } else if (pre > 0) {
      // find the offset within the block where the new records will be inserted
      split = cursor(pre - 1) + IO.NODESIZE;
    } else {
      // all insert operations will add data after first node.
      // i.e., there is no "insert before first document" statement
      throw Util.notExpected("Insertion at beginning of populated table.");
    }

    // number of bytes occupied by old records in the current block
    final int nold = npre - fpre << IO.NODEPOWER;
    // number of bytes occupied by old records which will be moved at the end
    final int moved = nold - split;

    // special case: all entries fit in the current block
    Buffer bf = bm.current();
    if (nold + nnew <= IO.BLOCKSIZE) {
      Array.move(bf.data, split, nnew, moved);
      System.arraycopy(entries, 0, bf.data, split, nnew);
      bf.dirty = true;

      // increment first pre-values of blocks after the last modified block
      for (int i = page + 1; i < used; ++i) fpres[i] += nr;
      // update cached variables (fpre is not changed)
      npre += nr;
      meta.size += nr;
      return;
    }

    // append old entries at the end of the new entries
    final byte[] all = new byte[nnew + moved];
    System.arraycopy(entries, 0, all, 0, nnew);
    System.arraycopy(bf.data, split, all, nnew, moved);

    // fill in the current block with new entries
    // number of bytes which fit in the first block
    int nrem = IO.BLOCKSIZE - split;
    if (nrem > 0) {
      System.arraycopy(all, 0, bf.data, split, nrem);
      bf.dirty = true;
    }

    // number of new required blocks and remaining bytes
    final int req = all.length - nrem;
    int needed = req / IO.BLOCKSIZE;
    final int remain = req % IO.BLOCKSIZE;

    if (remain > 0) {
      // check if the last entries can fit in the block after the current one
      if (page + 1 < used) {
        final int o = occSpace(page + 1) << IO.NODEPOWER;
        if (remain <= IO.BLOCKSIZE - o) {
          // copy the last records
          readPage(page + 1);
          bf = bm.current();
          System.arraycopy(bf.data, 0, bf.data, remain, o);
          System.arraycopy(all, all.length - remain, bf.data, 0, remain);
          bf.dirty = true;
          // reduce the pre value, since it will be later incremented with nr
          fpres[page] -= remain >>> IO.NODEPOWER;
          // go back to the previous block
          readPage(page - 1);
        } else {
          // there is not enough space in the block - allocate a new one
          ++needed;
        }
      } else {
        // this is the last block - allocate a new one
        ++needed;
      }
    }

    // number of expected blocks: existing blocks + needed block - empty blocks
    final int exp = blocks + needed - (blocks - used);
    if (exp > fpres.length) {
      // resize directory arrays if existing ones are too small
      final int ns = Math.max(fpres.length << 1, exp);
      fpres = Arrays.copyOf(fpres, ns);
      pages = Arrays.copyOf(pages, ns);
    }

    // make place for the blocks where the new entries will be written
    Array.move(fpres, page + 1, needed, used - page - 1);
    Array.move(pages, page + 1, needed, used - page - 1);

    // write the all remaining entries
    while (needed-- > 0) {
      freeBlock();
      nrem += write(all, nrem);
      fpres[page] = fpres[page - 1] + IO.ENTRIES;
      pages[page] = (int) bm.current().pos;
    }

    // increment all fpre values after the last modified block
    for (int i = page + 1; i < used; ++i) fpres[i] += nr;

    meta.size += nr;

    // update cached variables
    fpre = fpres[page];
    npre = page + 1 < used && fpres[page + 1] < meta.size ? fpres[page + 1] : meta.size;
  }