Package org.rabinfingerprint.fingerprint

Source Code of org.rabinfingerprint.fingerprint.RabinFingerprintLongWindowed

package org.rabinfingerprint.fingerprint;

import java.math.BigInteger;

import org.rabinfingerprint.datastructures.CircularByteQueue;
import org.rabinfingerprint.fingerprint.Fingerprint.WindowedFingerprint;
import org.rabinfingerprint.polynomial.Polynomial;

public class RabinFingerprintLongWindowed extends RabinFingerprintLong implements WindowedFingerprint<Polynomial> {

  protected final CircularByteQueue byteWindow;
  protected final long bytesPerWindow;
  protected final long[] popTable;

  public RabinFingerprintLongWindowed(Polynomial poly, long bytesPerWindow) {
    super(poly);
    this.bytesPerWindow = bytesPerWindow;
    this.byteWindow = new CircularByteQueue((int) bytesPerWindow + 1);
    this.popTable = new long[256];
    precomputePopTable();
  }

  public RabinFingerprintLongWindowed(RabinFingerprintLongWindowed that) {
    super(that);
    this.bytesPerWindow = that.bytesPerWindow;
    this.byteWindow = new CircularByteQueue((int) bytesPerWindow + 1);
    this.popTable = that.popTable;
  }

  private void precomputePopTable() {
    for (int i = 0; i < 256; i++) {
      Polynomial f = Polynomial.createFromLong(i);
      f = f.shiftLeft(BigInteger.valueOf(bytesPerWindow * 8));
      f = f.mod(poly);
      popTable[i] = f.toBigInteger().longValue();
    }
  }

  @Override
  public void pushBytes(final byte[] bytes) {
    for (byte b : bytes) {
      int j = (int) ((fingerprint >> shift) & 0x1FF);
      fingerprint = ((fingerprint << 8) | (b & 0xFF)) ^ pushTable[j];
      byteWindow.add(b);
      if (byteWindow.isFull()) popByte();
    }
  }

  @Override
  public void pushBytes(final byte[] bytes, final int offset, final int length) {
    final int max = offset + length;
    int i = offset;
    while (i < max) {
      byte b = bytes[i++];
      int j = (int) ((fingerprint >> shift) & 0x1FF);
      fingerprint = ((fingerprint << 8) | (b & 0xFF)) ^ pushTable[j];
      byteWindow.add(b);
      if (byteWindow.isFull()) popByte();
    }
  }

  @Override
  public void pushByte(byte b) {
    int j = (int) ((fingerprint >> shift) & 0x1FF);
    fingerprint = ((fingerprint << 8) | (b & 0xFF)) ^ pushTable[j];
    byteWindow.add(b);
    if (byteWindow.isFull()) popByte();
  }

  /**
   * Removes the contribution of the first byte in the byte queue from the
   * fingerprint.
   *
   * {@link RabinFingerprintPolynomial#popByte}
   */
  public void popByte() {
    byte b = byteWindow.poll();
    fingerprint ^= popTable[(b & 0xFF)];
  }

  @Override
  public void reset() {
    super.reset();
    byteWindow.clear();
  }
}
TOP

Related Classes of org.rabinfingerprint.fingerprint.RabinFingerprintLongWindowed

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.