/**
  * 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;
 }
 @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;
   }
 }
Exemple #3
0
  public static void runTests() {
    try {

      // SHA1 sha1Jmule = new SHA1();
      MessageDigest sha1Sun = MessageDigest.getInstance("SHA-1");
      SHA1 sha1Gudy = new SHA1();
      // SHA1Az shaGudyResume = new SHA1Az();

      ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);

      File dir = new File(dirname);
      File[] files = dir.listFiles();

      for (int i = 0; i < files.length; i++) {
        FileChannel fc = new RandomAccessFile(files[i], "r").getChannel();

        System.out.println("Testing " + files[i].getName() + " ...");

        while (fc.position() < fc.size()) {
          fc.read(buffer);
          buffer.flip();

          byte[] raw = new byte[buffer.limit()];
          System.arraycopy(buffer.array(), 0, raw, 0, raw.length);

          sha1Gudy.update(buffer);
          sha1Gudy.saveState();
          ByteBuffer bb = ByteBuffer.wrap(new byte[56081]);
          sha1Gudy.digest(bb);
          sha1Gudy.restoreState();

          sha1Sun.update(raw);

          buffer.clear();
        }

        byte[] sun = sha1Sun.digest();
        sha1Sun.reset();

        byte[] gudy = sha1Gudy.digest();
        sha1Gudy.reset();

        if (Arrays.equals(sun, gudy)) {
          System.out.println("  SHA1-Gudy: OK");
        } else {
          System.out.println("  SHA1-Gudy: FAILED");
        }

        buffer.clear();
        fc.close();
        System.out.println();
      }

    } catch (Throwable e) {
      Debug.printStackTrace(e);
    }
  }
  /**
   * Concat arrays in one.
   *
   * @param arrays Arrays.
   * @return Summary array.
   */
  public static int[] concat(int[]... arrays) {
    assert arrays != null;
    assert arrays.length > 1;

    int len = 0;

    for (int[] a : arrays) len += a.length;

    int[] r = Arrays.copyOf(arrays[0], len);

    for (int i = 1, shift = 0; i < arrays.length; i++) {
      shift += arrays[i - 1].length;
      System.arraycopy(arrays[i], 0, r, shift, arrays[i].length);
    }

    return r;
  }
 private void dispatchMessage(
     TcpAddress incomingAddress, ByteBuffer byteBuffer, long bytesRead) {
   byteBuffer.flip();
   if (logger.isDebugEnabled()) {
     logger.debug(
         "Received message from "
             + incomingAddress
             + " with length "
             + bytesRead
             + ": "
             + new OctetString(byteBuffer.array(), 0, (int) bytesRead).toHexString());
   }
   ByteBuffer bis;
   if (isAsyncMsgProcessingSupported()) {
     byte[] bytes = new byte[(int) bytesRead];
     System.arraycopy(byteBuffer.array(), 0, bytes, 0, (int) bytesRead);
     bis = ByteBuffer.wrap(bytes);
   } else {
     bis = ByteBuffer.wrap(byteBuffer.array(), 0, (int) bytesRead);
   }
   fireProcessMessage(incomingAddress, bis);
 }
 /**
  * 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;
 }
  @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;
  }