/**
* Copyright 2010 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
package org.drools.core.util;
import org.drools.common.InternalFactHandle;
import org.drools.core.util.AbstractHashTable.Index;
import org.drools.reteoo.LeftTuple;
import org.drools.reteoo.RightTuple;
import org.drools.reteoo.RightTupleMemory;
public class RightTupleList
implements
RightTupleMemory,
Entry {
private static final long serialVersionUID = 510l;
public Entry previous;
public Entry next;
public RightTuple first;
public RightTuple last;
private int hashCode;
private Index index;
private TupleHashTableIterator iterator;
public RightTupleList() {
// this is not an index bucket
this.hashCode = 0;
this.index = null;
}
public RightTupleList(final Index index,
final int hashCode) {
this.index = index;
this.hashCode = hashCode;
}
public RightTupleList(final Index index,
final int hashCode,
final Entry next) {
this.index = index;
this.hashCode = hashCode;
this.next = next;
}
public RightTupleList(RightTupleList p, final Entry next) {
this.index = p.index;
this.hashCode = p.hashCode;
this.next = next;
this.first = p.first;
this.last = p.last;
}
public RightTuple getFirst(LeftTuple leftTuple, InternalFactHandle factHandle) {
return this.first;
}
public RightTuple getFirst(RightTuple leftTuple) {
return this.first;
}
public RightTuple getLast(LeftTuple leftTuple) {
return this.last;
}
public void add(final RightTuple rightTuple) {
if ( this.last != null ) {
this.last.setNext( rightTuple );
rightTuple.setPrevious( this.last );
this.last = rightTuple;
} else {
this.first = rightTuple;
this.last = rightTuple;;
}
}
/**
* We assume that this rightTuple is contained in this hash table
*/
public void remove(final RightTuple rightTuple) {
RightTuple previous = (RightTuple) rightTuple.getPrevious();
RightTuple next = (RightTuple) rightTuple.getNext();
if ( previous != null && next != null ) {
// remove from middle
previous.setNext( next );
next.setPrevious( previous );
} else if ( next != null ) {
// remove from first
this.first = next;
next.setPrevious( null );
} else if ( previous != null ) {
// remove from end
this.last = previous;
previous.setNext( null );
} else {
// remove everything
this.last = null;
this.first = null;
}
rightTuple.setPrevious( null );
rightTuple.setNext( null );
}
public RightTuple get(final InternalFactHandle handle) {
RightTuple current = this.first;
while ( current != null ) {
if ( handle == current.getFactHandle() ) {
return current;
}
current = (RightTuple) current.getNext();
}
return null;
}
public boolean contains(final InternalFactHandle handle) {
return get( handle ) != null;
}
public RightTuple get(final RightTuple rightTuple) {
InternalFactHandle handle = rightTuple.getFactHandle();
RightTuple current = this.first;
while ( current != null ) {
if ( handle == current.getFactHandle() ) {
return current;
}
current = (RightTuple) current.getNext();
}
return null;
}
public boolean contains(final RightTuple rightTuple) {
return get( rightTuple ) != null;
}
public int size() {
int i = 0;
RightTuple current = this.first;
while ( current != null ) {
current = (RightTuple) current.getNext();
i++;
}
return i;
}
public Iterator iterator() {
if ( this.iterator == null ) {
this.iterator = new TupleHashTableIterator();
}
this.iterator.reset( this.first );
return this.iterator;
}
public static class TupleHashTableIterator
implements
Iterator {
private RightTuple current;
public void reset(RightTuple first) {
this.current = first;
}
public Object next() {
if ( this.current != null ) {
RightTuple returnValue = this.current;
this.current = (RightTuple) current.getNext();
return returnValue;
} else {
return null;
}
}
public void remove() {
// do nothing
}
}
public boolean matches(final Object object,
final int objectHashCode) {
return this.hashCode == objectHashCode && this.index.equal( this.first.getFactHandle().getObject(),
object );
}
public boolean matches(final LeftTuple tuple,
final int tupleHashCode,
final InternalFactHandle factHandle) {
if ( this.hashCode != tupleHashCode ) {
return false;
}
if ( this.first.getFactHandle() == factHandle ) {
RightTuple rightTuple = ( RightTuple ) this.first.getNext();
if ( rightTuple != null ) {
return this.index.equal( rightTuple.getFactHandle().getObject(),
tuple );
}
}
return this.index.equal( this.first.getFactHandle().getObject(),
tuple );
}
public RightTuple[] toArray() {
int size = size();
RightTuple[] tuples = new RightTuple[size];
RightTuple current = first;
for ( int i = 0; i < size; i++ ) {
tuples[i] = current;
current = (RightTuple) current.getNext();
}
return tuples;
}
public int hashCode() {
return this.hashCode;
}
public boolean equals(final Object object) {
final RightTupleList other = (RightTupleList) object;
return this.hashCode == other.hashCode && this.index == other.index;
}
public Entry getNext() {
return this.next;
}
public void setNext(final Entry next) {
this.next = next;
}
public boolean isIndexed() {
return (this.index != null);
}
public Index getIndex() {
return this.index;
}
public String toString() {
StringBuilder builder = new StringBuilder();
for ( RightTuple rightTuple = (RightTuple) this.first; rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
builder.append( rightTuple );
}
return builder.toString();
}
}