/**
* 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 java.util.concurrent.atomic.AtomicReference;
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 ConcurrentRightTupleList
implements
RightTupleMemory,
Entry {
private static final long serialVersionUID = 510l;
public AtomicReference<Entry> previous;
public AtomicReference<Entry> next;
public AtomicReference<RightTuple> first;
public AtomicReference<RightTuple> last;
private final int hashCode;
private final Index index;
public ConcurrentRightTupleList() {
// this is not an index bucket
this.hashCode = 0;
this.index = null;
this.previous = new AtomicReference<Entry>();
this.next = new AtomicReference<Entry>();
this.first = new AtomicReference<RightTuple>();
this.last = new AtomicReference<RightTuple>();
}
public ConcurrentRightTupleList(final Index index,
final int hashCode) {
this.index = index;
this.hashCode = hashCode;
}
public RightTuple getFirst(LeftTuple leftTuple, InternalFactHandle factHandle ) {
return this.first.get();
}
public RightTuple getFirst(RightTuple rightTuple) {
return this.first.get();
}
public RightTuple getLast(LeftTuple leftTuple) {
return this.last.get();
}
public void add(final RightTuple rightTuple) {
if ( this.last != null ) {
this.last.get().setNext( rightTuple );
rightTuple.setPrevious( this.last.get() );
this.last.set( rightTuple );
} else {
this.first.set( rightTuple );
this.last.set( 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.set( next );
next.setPrevious( null );
} else if ( previous != null ) {
// remove from end
this.last.set( 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.get();
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.get();
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.get();
while ( current != null ) {
current = (RightTuple) current.getNext();
i++;
}
return i;
}
public Iterator iterator() {
throw new UnsupportedOperationException();
}
public boolean matches(final Object object,
final int objectHashCode) {
return this.hashCode == objectHashCode && this.index.equal( this.first.get().getFactHandle().getObject(),
object );
}
public boolean matches(final LeftTuple tuple,
final int tupleHashCode) {
return this.hashCode == tupleHashCode && this.index.equal( this.first.get().getFactHandle().getObject(),
tuple );
}
public int hashCode() {
return this.hashCode;
}
public boolean equals(final Object object) {
final ConcurrentRightTupleList other = (ConcurrentRightTupleList) object;
return this.hashCode == other.hashCode && this.index == other.index;
}
public Entry getNext() {
return this.next.get();
}
public void setNext(final Entry next) {
this.next.set( next );
}
public boolean isIndexed() {
return (this.index != null);
}
public String toString() {
StringBuilder builder = new StringBuilder();
for ( RightTuple rightTuple = (RightTuple) this.first.get(); rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
builder.append( rightTuple );
}
return builder.toString();
}
public Entry[] toArray() {
throw new UnsupportedOperationException( "method is not implemented yet" );
}
public void clear() {
RightTuple rightTuple = null;
while((rightTuple = (RightTuple) iterator().next()) != null) {
remove(rightTuple);
}
}
}