All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.deephaven.engine.rowset.impl.rsp.container.ArrayContainerRangeIterator Maven / Gradle / Ivy

package io.deephaven.engine.rowset.impl.rsp.container;


final class ArrayContainerRangeIterator implements SearchRangeIterator {
    private final ArrayContainer parent;

    private int nextPos;
    private int start;
    private int end;

    public ArrayContainerRangeIterator(final ArrayContainer p, final int initialSkipCount) {
        parent = p;
        nextPos = initialSkipCount;
    }

    public ArrayContainerRangeIterator(final ArrayContainerRangeIterator other) {
        nextPos = other.nextPos;
        start = other.start;
        end = other.end;
        parent = other.parent;

    }

    public ArrayContainerRangeIterator copy() {
        return new ArrayContainerRangeIterator(this);
    }

    @Override
    public boolean hasNext() {
        return nextPos < parent.cardinality;
    }

    @Override
    public int start() {
        return start;
    }

    @Override
    public int end() {
        return end;
    }

    @Override
    public void next() {
        start = ContainerUtil.toIntUnsigned(parent.content[nextPos++]);
        end = start + 1;
        while (nextPos < parent.cardinality) {
            int v = ContainerUtil.toIntUnsigned(parent.content[nextPos]);
            if (v != end) {
                break;
            }
            ++nextPos;
            end = v + 1;
        }
    }

    /**
     * Set the current iterator range based on the index idx and value v provided. Look for a range starting at the
     * value at index idx. The provided value v is to the left or inside that range, never to the right. Set the end of
     * the current iterator range to the end of the range at idx. Set the current iterator range start to v if v is
     * inside the range, or the start of the range at idx otherwise.
     *
     * @param v A value to the left or inside the range at idx
     * @param idx a valid index inside our contents array.
     */
    private void setRangeBoundariesFor(final int v, final int idx) {
        // find actual range boundaries.
        int vi = ContainerUtil.toIntUnsigned(parent.content[idx]);
        end = vi + 1;
        int iend = idx;
        for (int j = idx + 1; j < parent.cardinality; ++j) {
            final int vj = ContainerUtil.toIntUnsigned(parent.content[j]);
            if (vj - vi > j - idx) {
                break;
            } else {
                iend = j;
                end = vj + 1;
            }
        }
        start = Math.max(v, vi);
        nextPos = iend + 1;
    }

    @Override
    public boolean advance(final int v) {
        if (nextPos > 0 && end > v) {
            return true;
        }
        int i = ContainerUtil.unsignedBinarySearch(parent.content, nextPos, parent.cardinality,
                ContainerUtil.lowbits(v));
        if (i < 0) {
            i = -i - 1;
        }
        if (i >= parent.cardinality) {
            nextPos = parent.cardinality;
            return false;
        }
        setRangeBoundariesFor(v, i);
        return true;
    }

    @Override
    public boolean search(final ContainerUtil.TargetComparator comp) {
        if (nextPos == 0) {
            if (!hasNext()) {
                return false;
            }
            next();
        }
        int c = comp.directionFrom(end - 1);
        if (c <= 0) {
            if (c == 0) {
                start = end - 1;
                return true;
            }
            if (start == end - 1) {
                return false;
            }
            c = comp.directionFrom(start);
            if (c < 0) {
                return false;
            }
            if (c == 0) {
                return true;
            }
            int j = ContainerUtil.rangeSearch(start + 1, end - 1, comp);
            if (j == -1) {
                return true;
            }
            start = j;
            return true;
        }
        int i = ContainerUtil.search(parent.content, nextPos, parent.cardinality, comp);
        if (i < 0) {
            setRangeBoundariesFor(start, nextPos - 1);
            return true;
        }
        setRangeBoundariesFor(parent.content[i], i);
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy