Beispiel #1
0
  /**
   * Sets the output text.
   *
   * @param t output text
   * @param s text size
   */
  public final void setText(final byte[] t, final int s) {
    // remove invalid characters and compare old with new string
    int ns = 0;
    final int ts = text.size();
    final byte[] tt = text.text();
    boolean eq = true;
    for (int r = 0; r < s; ++r) {
      final byte b = t[r];
      // support characters, highlighting codes, tabs and newlines
      if (b >= ' ' || b <= TokenBuilder.MARK || b == 0x09 || b == 0x0A) {
        t[ns++] = t[r];
      }
      eq &= ns < ts && ns < s && t[ns] == tt[ns];
    }
    eq &= ns == ts;

    // new text is different...
    if (!eq) {
      text = new BaseXTextTokens(Arrays.copyOf(t, ns));
      rend.setText(text);
      scroll.pos(0);
    }
    if (undo != null) undo.store(t.length != ns ? Arrays.copyOf(t, ns) : t, 0);
    SwingUtilities.invokeLater(calc);
  }
Beispiel #2
0
 /**
  * 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;
 }
Beispiel #3
0
 @Override
 public Expr optimize(final QueryContext qc, final VarScope scp) throws QueryException {
   // number of predicates may change in loop
   for (int p = 0; p < preds.length; p++) {
     final Expr pred = preds[p];
     if (pred instanceof CmpG || pred instanceof CmpV) {
       final Cmp cmp = (Cmp) pred;
       if (cmp.exprs[0].isFunction(Function.POSITION)) {
         final Expr e2 = cmp.exprs[1];
         final SeqType st2 = e2.seqType();
         // position() = last() -> last()
         // position() = $n (numeric) -> $n
         if (e2.isFunction(Function.LAST) || st2.one() && st2.type.isNumber()) {
           if (cmp instanceof CmpG && ((CmpG) cmp).op == OpG.EQ
               || cmp instanceof CmpV && ((CmpV) cmp).op == OpV.EQ) {
             qc.compInfo(OPTWRITE, pred);
             preds[p] = e2;
           }
         }
       }
     } else if (pred instanceof And) {
       if (!pred.has(Flag.FCS)) {
         // replace AND expression with predicates (don't swap position tests)
         qc.compInfo(OPTPRED, pred);
         final Expr[] and = ((Arr) pred).exprs;
         final int m = and.length - 1;
         final ExprList el = new ExprList(preds.length + m);
         for (final Expr e : Arrays.asList(preds).subList(0, p)) el.add(e);
         for (final Expr a : and) {
           // wrap test with boolean() if the result is numeric
           el.add(Function.BOOLEAN.get(null, info, a).optimizeEbv(qc, scp));
         }
         for (final Expr e : Arrays.asList(preds).subList(p + 1, preds.length)) el.add(e);
         preds = el.finish();
       }
     } else if (pred instanceof ANum) {
       final ANum it = (ANum) pred;
       final long i = it.itr();
       if (i == it.dbl()) {
         preds[p] = Pos.get(i, info);
       } else {
         qc.compInfo(OPTREMOVE, this, pred);
         return Empty.SEQ;
       }
     } else if (pred.isValue()) {
       if (pred.ebv(qc, info).bool(info)) {
         qc.compInfo(OPTREMOVE, this, pred);
         preds = Array.delete(preds, p--);
       } else {
         // handle statically known predicates
         qc.compInfo(OPTREMOVE, this, pred);
         return Empty.SEQ;
       }
     }
   }
   return this;
 }
Beispiel #4
0
 /** Finishes the index creation. */
 void finish() {
   if (reorder == null) return;
   for (int i = 1; i < reorder.size(); i++) {
     if (reorder.get(i)) Arrays.sort(idsList.get(i), 0, lenList.get(i));
   }
   reorder = null;
 }
Beispiel #5
0
 @Override
 public void rehash() {
   super.rehash();
   final int s = size << 1;
   ids = Array.copyOf(ids, s);
   len = Arrays.copyOf(len, s);
 }
Beispiel #6
0
 /**
  * Binary search of a key in a list. If there are several hits the last one is returned.
  *
  * @param a array to search into
  * @param e key to search for
  * @return index of the found hit or where the key ought to be inserted
  */
 private int sortedLastIndexOf(final int[] a, final int e) {
   int i = Arrays.binarySearch(a, 0, rows, e);
   if (i >= 0) {
     while (++i < rows && a[i] == e) ;
     return i - 1;
   }
   return i;
 }
Beispiel #7
0
 @Override
 public Expr copy(final QueryContext ctx, final VarScope scp, final IntObjMap<Var> vs) {
   final Expr[] copy = copyAll(ctx, scp, vs, expr);
   final int last = copy.length - 1;
   final Expr[] args = Arrays.copyOf(copy, last);
   final DynFuncCall call = new DynFuncCall(info, sc, updating, copy[last], args);
   if (inlinedFrom != null) call.inlinedFrom = inlinedFrom.clone();
   return copyType(call);
 }
Beispiel #8
0
  /**
   * Scans an external ID.
   *
   * @param f full flag
   * @param r root flag
   * @return id
   * @throws IOException I/O exception
   */
  private byte[] externalID(final boolean f, final boolean r) throws IOException {
    byte[] cont = null;
    final boolean pub = consume(PUBLIC);
    if (pub || consume(SYSTEM)) {
      checkS();
      if (pub) {
        pubidLit();
        if (f) checkS();
      }
      final int qu = consume(); // [11]
      if (qu == '\'' || qu == '"') {
        int ch;
        final TokenBuilder tok = new TokenBuilder();
        while ((ch = nextChar()) != qu) tok.add(ch);
        if (!f) return null;
        final String name = string(tok.finish());
        if (!dtd && r) return cont;

        final XMLInput tin = input;
        try {
          final IO file = input.io().merge(name);
          cont = file.read();
        } catch (final IOException ex) {
          Util.debug(ex);
          // skip unknown DTDs/entities
          cont = new byte[] {'?'};
        }
        input = new XMLInput(new IOContent(cont, name));

        if (consume(XDECL)) {
          check(XML);
          s();
          if (version()) checkS();
          s();
          if (encoding() == null) error(TEXTENC);
          ch = nextChar();
          if (s(ch)) ch = nextChar();
          if (ch != '?') error(WRONGCHAR, '?', ch);
          ch = nextChar();
          if (ch != '>') error(WRONGCHAR, '>', ch);
          cont = Arrays.copyOfRange(cont, input.pos(), cont.length);
        }

        s();
        if (r) {
          extSubsetDecl();
          if (!consume((char) 0)) error(INVEND);
        }
        input = tin;
      } else {
        if (f) error(SCANQUOTE, (char) qu);
        prev(1);
      }
    }
    return cont;
  }
Beispiel #9
0
 /**
  * Sets the output text.
  *
  * @param text output text
  * @param size text size
  */
 public final void setText(final byte[] text, final int size) {
   byte[] txt = text;
   if (Token.contains(text, '\r')) {
     // remove carriage returns
     int ns = 0;
     for (int r = 0; r < size; ++r) {
       final byte b = text[r];
       if (b != '\r') text[ns++] = b;
     }
     // new text is different...
     txt = Arrays.copyOf(text, ns);
   } else if (text.length != size) {
     txt = Arrays.copyOf(text, size);
   }
   if (editor.text(txt)) {
     if (hist != null) hist.store(txt, editor.pos(), 0);
   }
   if (isShowing()) resizeCode.invokeLater();
 }
Beispiel #10
0
 /**
  * Indexes the specified keys and values.
  *
  * @param key key
  * @param id id value
  * @return index position
  */
 public int index(final byte[] key, final int id) {
   int i = add(key);
   if (i > 0) {
     ids[i] = new int[] {id};
   } else {
     i = -i;
     final int l = len[i];
     if (l == ids[i].length) ids[i] = Arrays.copyOf(ids[i], l << 1);
     ids[i][l] = id;
   }
   len[i]++;
   return i;
 }
Beispiel #11
0
  /**
   * Inserts a new record.
   *
   * @param pre record PRE
   * @param id record ID
   * @param c number of inserted records
   */
  public void insert(final int pre, final int id, final int c) {
    if (rows == 0 && pre == id && id == baseid + 1) {
      // no mapping and we append at the end => nothing to do
      baseid += c;
      return;
    }

    int pos = 0;
    int inc = c;
    int oid = pre;

    if (rows > 0) {
      pos = Arrays.binarySearch(pres, 0, rows, pre);
      if (pos < 0) {
        pos = -pos - 1;
        if (pos != 0) {
          // check if inserting into an existing id interval
          final int prev = pos - 1;
          final int prevcnt = nids[prev] - fids[prev] + 1;
          final int prevpre = pres[prev];

          if (pre < prevpre + prevcnt) {
            // split the id interval
            final int split = pre - prevpre;
            final int fid = fids[prev] + split;

            // add a new next interval
            add(pos, pre, fid, nids[prev], incs[prev], oids[prev]);

            // shrink the previous interval
            nids[prev] = fid - 1;
            incs[prev] -= prevcnt - split;

            oid = oids[prev];
            inc += incs[prev];
          } else {
            oid = pre - incs[prev];
            inc += incs[prev];
          }
        }
      } else if (pos > 0) {
        oid = oids[pos];
        inc += incs[pos - 1];
      }

      increment(pos, c);
    }

    // add the new interval
    add(pos, pre, id, id + c - 1, inc, oid);
  }
Beispiel #12
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);
  }
Beispiel #13
0
  @Override
  public Expr optimize(final QueryContext ctx, final VarScope scp) throws QueryException {
    final int ar = expr.length - 1;
    final Expr f = expr[ar];
    final Type t = f.type().type;
    if (t instanceof FuncType) {
      final FuncType ft = (FuncType) t;
      if (ft.args != null && ft.args.length != ar) throw INVARITY.get(info, f, ar);
      if (ft.ret != null) type = ft.ret;
    }

    if (f instanceof XQFunctionExpr) {
      // maps can only contain fully evaluated Values, so this is safe
      if (allAreValues() && f instanceof Map) return optPre(value(ctx), ctx);

      // try to inline the function
      if (!(f instanceof FuncItem && comesFrom((FuncItem) f)) && !updating) {
        final Expr[] args = Arrays.copyOf(expr, expr.length - 1);
        final Expr inl = ((XQFunctionExpr) f).inlineExpr(args, ctx, scp, info);
        if (inl != null) return inl;
      }
    }
    return this;
  }
Beispiel #14
0
 @Override
 protected void rehash() {
   super.rehash();
   funcs = Arrays.copyOf(funcs, size << 1);
 }
Beispiel #15
0
 /**
  * Adds the specified prefix and URI reference.
  *
  * @param prefix prefix reference
  * @param uri uri reference
  */
 void add(final int prefix, final int uri) {
   final int s = values.length;
   values = Arrays.copyOf(values, s + 2);
   values[s] = prefix;
   values[s + 1] = uri;
 }
Beispiel #16
0
 @Override
 protected void rehash(final int sz) {
   super.rehash(sz);
   values = Arrays.copyOf(values, sz);
 }
Beispiel #17
0
 /**
  * Returns the byte buffer.
  *
  * @return byte buffer
  */
 private byte[] buffer() {
   final byte[] bb = bp == b.length ? b : Arrays.copyOf(b, bp);
   bp = 0;
   return bb;
 }
Beispiel #18
0
 @Override
 public void checkUp() throws QueryException {
   checkNoneUp(Arrays.copyOf(expr, expr.length - 1));
 }
Beispiel #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;
  }