package org.mulgara.store.xa; import org.apache.log4j.Logger; import org.mulgara.query.TuplesException; import org.mulgara.store.tuples.DenseLongMatrix; /** * * * @created 2004-03-22 * * @author Andrae Muys * * @version $Revision: 1.9 $ * * @modified $Date: 2005/01/05 04:59:12 $ * * @maintenanceAuthor $Author: newmana $ * * @company <A href="mailto:info@PIsoftware.com">Plugged In Software</A> * * @copyright ©2004 <a href="http://www.pisoftware.com/">Plugged In * Software Pty Ltd</a> * * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a> */ public class MemoryCacheLine extends CacheLine { protected DenseLongMatrix cache; protected long[] currentTuple; protected int current; protected int previous; protected long[] prefix; protected int index; protected int width; private long[] pivotTuple; @SuppressWarnings("unused") private final static Logger logger = Logger.getLogger(MemoryCacheLine.class); public MemoryCacheLine(DenseLongMatrix buffer, int size) { super(size); this.cache = buffer; this.index = 0; this.currentTuple = new long[buffer.getWidth()]; this.current = 0; // this.previousTuple = null; this.previous = -1; this.width = buffer.getLength(); this.pivotTuple = new long[buffer.getWidth()]; } public boolean isEmpty() { if (prefix == null) { return index >= segmentSize; } else { return index >= segmentSize || matchPrefix(currentTuple, prefix) != 0; } } public void advance() { // logger.warn("advance() called on " + System.identityHashCode(this)); index++; previous = current; current = (index < segmentSize) ? index : 0; currentTuple = getCurrentTuple(currentTuple); } public void reset(long[] prefix) throws TuplesException { super.reset(prefix); // logger.warn("reset() called on " + System.identityHashCode(this)); assert prefix.length <= cache.getWidth(); this.prefix = prefix.length > 0 ? (long[])prefix.clone() : null; if (this.prefix == null) { index = -1; } else { index = findPrefix(this.prefix) - 1; } } public long[] getCurrentTuple(long[] tuple) { return cache.loadRow(tuple, current); } public long[] getPreviousTuple(long[] tuple) { return cache.loadRow(tuple, previous); } public void close(int closer) throws TuplesException { super.close(closer); // logger.warn("Closed " + System.identityHashCode(this)); cache = null; current = -1; previous = -1; } public Object clone() { // FIXME: This is probably not correct behaviour, there is probabaly state that needs duplicating. MemoryCacheLine copy = (MemoryCacheLine)super.clone(); copy.currentTuple = (long[])currentTuple.clone(); copy.pivotTuple = (long[])pivotTuple.clone(); // logger.warn("Cloned " + System.identityHashCode(this) + " -> " + System.identityHashCode(copy)); return copy; } private int findPrefix(long[] prefix) { int index = findPrefix(prefix, 0, segmentSize - 1, -1); return index >= 0 ? index : segmentSize; } private int findPrefix(long[] prefix, int left, int right, int found) { if (left > right) { return found; } int pivot = left + ((right - left) / 2); switch (matchPrefix(cache.loadRow(pivotTuple, pivot), prefix)) { case -1: return findPrefix(prefix, pivot + 1, right, found); case 0: return findPrefix(prefix, left, pivot - 1, pivot); case +1: return findPrefix(prefix, left, pivot - 1, found); } return 0; } }