Package org.drools.core.util.index

Source Code of org.drools.core.util.index.RightTupleIndexRangeRBTree

package org.drools.core.util.index;

import org.drools.core.common.InternalFactHandle;
import org.drools.core.reteoo.LeftTuple;
import org.drools.core.reteoo.RightTuple;
import org.drools.core.reteoo.RightTupleMemory;
import org.drools.core.util.AbstractHashTable.FieldIndex;
import org.drools.core.util.Entry;
import org.drools.core.util.FastIterator;
import org.drools.core.util.Iterator;
import org.drools.core.util.RBTree;
import org.drools.core.util.index.IndexUtil.ConstraintType;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.List;

public class RightTupleIndexRangeRBTree implements RightTupleMemory, Externalizable {

    private RBTree<Comparable<Comparable>, RightTupleList> tree;

    private FieldIndex ascendingIndex;
    private ConstraintType ascendingConstraintType;

    private FieldIndex descendingIndex;
    private ConstraintType descendingConstraintType;
   
    private RightTupleBoundedFastIterator rightTupleBoundedFastIterator;

    private int size;

    public RightTupleIndexRangeRBTree() {
        // constructor for serialisation
    }

    public RightTupleIndexRangeRBTree(ConstraintType ascendingConstraintType, FieldIndex ascendingIndex,
                                      ConstraintType descendingConstraintType, FieldIndex descendingIndex) {
        this.ascendingIndex = ascendingIndex;
        this.ascendingConstraintType = ascendingConstraintType;
        this.descendingIndex = descendingIndex;
        this.descendingConstraintType = descendingConstraintType;
        tree = new RBTree<Comparable<Comparable>, RightTupleList>();
    }


    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject( tree );
        out.writeObject( ascendingIndex );
        out.writeObject( ascendingConstraintType );
        out.writeObject( descendingIndex );
        out.writeObject( descendingConstraintType );
        out.writeInt(size);
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        tree = (RBTree<Comparable<Comparable>, RightTupleList>) in.readObject();
        ascendingIndex = (FieldIndex) in.readObject();
        ascendingConstraintType = (ConstraintType) in.readObject();
        descendingIndex = (FieldIndex) in.readObject();
        descendingConstraintType = (ConstraintType) in.readObject();
        size = in.readInt();
    }

    public void add(RightTuple tuple) {
        Comparable key = getRightIndexedValue(tuple);
        RightTupleList list = tree.lookup(key);
        if (list == null) {
            list = new RightTupleList();
            tree.insert(key, list);
        }
        list.add(tuple);
        size++;
    }

    public void remove(RightTuple tuple) {
        tuple.getMemory().remove(tuple);
        size--;
    }

    public void removeAdd(RightTuple tuple) {
        remove(tuple);
        add(tuple);
    }

    public boolean isIndexed() {
        return true;
    }

    public int size() {
        return size;
    }

    public Entry[] toArray() {
        FastIterator it = tree.fastIterator();
        if (it == null) {
            return new Entry[0];
        }

        List<Comparable> toBeRemoved = new ArrayList<Comparable>();
        List<RightTuple> result = new ArrayList<RightTuple>();

        RBTree.Node<Comparable<Comparable>, RightTupleList> node;
        while ( (node = (RBTree.Node<Comparable<Comparable>, RightTupleList>) it.next( null )) != null ) {
            RightTupleList bucket = node.value;
            if (bucket.size() == 0) {
                toBeRemoved.add(node.key);
            } else {
                RightTuple entry = bucket.getFirst();
                while (entry != null) {
                    result.add(entry);
                    entry = (RightTuple) entry.getNext();
                }
            }
        }

        for (Comparable key : toBeRemoved) {
            tree.delete(key);
        }

        return result.toArray(new LeftTuple[result.size()]);
    }

    public RightTuple getFirst(LeftTuple leftTuple, InternalFactHandle factHandle, FastIterator rightTupleIterator) {
        if ( rightTupleIterator instanceof RightTupleBoundedFastIterator ) {
            ((RightTupleBoundedFastIterator) rightTupleIterator).setUpperBound(leftTuple);
        }

        Comparable lowerBound = getLeftAscendingIndexedValue(leftTuple);
        RightTuple rightTuple = getNext(lowerBound, true);
        return rightTuple == null ? null : checkUpperBound(rightTuple, getLeftDescendingIndexedValue(leftTuple));
    }

    private RightTuple checkUpperBound(RightTuple rightTuple, Comparable upperBound) {
        int compResult = getRightIndexedValue(rightTuple).compareTo(upperBound);
        return compResult < 0 || (compResult == 0 && descendingConstraintType == ConstraintType.LESS_OR_EQUAL) ? rightTuple : null;
    }

    public Iterator iterator() {
        RightTupleList list = tree.first().value;
        RightTuple firstTuple = list != null ? list.first : null;
        return new FastIterator.IteratorAdapter(fastIterator(), firstTuple);
    }

    public boolean contains(RightTuple tuple) {
        Comparable key = getRightIndexedValue(tuple);
        return tree.lookup(key) != null;
    }

    public FastIterator fastIterator() {
        if ( rightTupleBoundedFastIterator != null ) {
            rightTupleBoundedFastIterator = new RightTupleBoundedFastIterator();
        }
        return rightTupleBoundedFastIterator;
    }

    public FastIterator fullFastIterator() {
        if ( rightTupleBoundedFastIterator != null ) {
            rightTupleBoundedFastIterator = new RightTupleBoundedFastIterator();
        }
        return rightTupleBoundedFastIterator;
    }

    public FastIterator fullFastIterator(RightTuple tuple) {
        FastIterator fastIterator = fullFastIterator();
        Comparable key = getRightIndexedValue(tuple);
        fastIterator.next(getNext(key, true));
        return fastIterator;
    }

    public IndexType getIndexType() {
        return IndexType.COMPARISON;
    }

    private RightTuple getNext(Comparable lowerBound, boolean first) {
        RBTree.Node<Comparable<Comparable>, RightTupleList> firstNode;
        while (true) {
            switch (ascendingConstraintType) {
                case GREATER_THAN:
                    firstNode = tree.findNearestNode(lowerBound, false, RBTree.Boundary.LOWER);
                    break;
                case GREATER_OR_EQUAL:
                    firstNode = tree.findNearestNode(lowerBound, first, RBTree.Boundary.LOWER);
                    break;
                default:
                    throw new UnsupportedOperationException("Cannot call remove constraint of type: " + ascendingConstraintType);
            }
            if (firstNode != null && firstNode.value.size() == 0) {
                tree.delete(firstNode.key);
            } else {
                break;
            }
        }
        return firstNode == null ? null : firstNode.value.getFirst();
    }

    private Comparable getLeftAscendingIndexedValue(LeftTuple leftTuple) {
        return (Comparable) ascendingIndex.getDeclaration().getExtractor().getValue(leftTuple.get(ascendingIndex.getDeclaration()).getObject());
    }

    private Comparable getLeftDescendingIndexedValue(LeftTuple leftTuple) {
        return (Comparable) descendingIndex.getDeclaration().getExtractor().getValue(leftTuple.get(descendingIndex.getDeclaration()).getObject());
    }

    private Comparable getRightIndexedValue(RightTuple rightTuple) {
        return (Comparable) ascendingIndex.getExtractor().getValue( rightTuple.getFactHandle().getObject() );
    }

    public class RightTupleBoundedFastIterator implements FastIterator {

        private Comparable upperBound;

        public void setUpperBound(LeftTuple leftTuple) {
            upperBound = getLeftDescendingIndexedValue(leftTuple);
        }

        public Entry next(Entry object) {
            if (object == null) {
                return null;
            }
            RightTuple rightTuple = (RightTuple) object;
            RightTuple next = (RightTuple) rightTuple.getNext();
            if (next != null) {
                return next;
            }
            Comparable key = getRightIndexedValue(rightTuple);
            next = getNext(key, false);
            return next == null ? null : checkUpperBound(next, upperBound);
        }

        public boolean isFullIterator() {
            return false;
        }
    }

    public void clear() {
        tree = new RBTree<Comparable<Comparable>, RightTupleList>();
    }
}
TOP

Related Classes of org.drools.core.util.index.RightTupleIndexRangeRBTree

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.