public void updateHash(byte[] input, int pos, int end) {
    // WINDOW_MASK
    int hPos = pos & 0x7FFF;
    int val = this.val;

    val = ((val << 5) ^ (pos + 2 < end ? input[pos + 2] & 0xFF : 0)) & 0x7FFF;

    hashVal[hPos] = val;
    int tmp = head[val];
    prev[hPos] = (tmp != -1 && hashVal[tmp] == val) ? tmp : hPos;
    head[val] = hPos;

    tmp = same[(pos - 1) & 0x7FFF];
    if (tmp < 1) {
      tmp = 1;
    }
    tmp += pos;
    byte b = input[pos];
    while (tmp < end && b == input[tmp]) {
      tmp++;
    }
    tmp -= pos;
    tmp--;
    same[hPos] = tmp;

    tmp = ((tmp - 3) & 0xFF) ^ val;
    hashVal2[hPos] = tmp;
    int h = head2[tmp];
    prev2[hPos] = h != -1 && hashVal2[h] == tmp ? h : hPos;
    head2[tmp] = hPos;

    this.val = val;
  }