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;
    }