com.bigdata.relation.rule.eval.AbstractSolutionBuffer Maven / Gradle / Ivy
package com.bigdata.relation.rule.eval;
import com.bigdata.relation.IMutableRelation;
import com.bigdata.relation.IRelation;
import com.bigdata.relation.accesspath.AbstractArrayBuffer;
import com.bigdata.relation.accesspath.IBuffer;
import com.bigdata.striterator.ChunkedArrayIterator;
import com.bigdata.striterator.ChunkedResolvingIterator;
import com.bigdata.striterator.IChunkedIterator;
import com.bigdata.striterator.IChunkedOrderedIterator;
/**
* Base class for {@link IBuffer} whose target is a mutation (insert, delete, or
* update) of some {@link IMutableRelation}.
*
* Note that this buffers chunks of {@link ISolution}s NOT relation
* elements.
*
* @author Bryan Thompson
* @version $Id$
*
* @param
* The generic type of the [R]elation elements.
*
* @see IMutableRelation
*/
abstract public class AbstractSolutionBuffer extends
AbstractArrayBuffer[]> {
private final IMutableRelation relation;
protected IMutableRelation getRelation() {
return relation;
}
/**
* @param capacity
*/
protected AbstractSolutionBuffer(final int capacity,
final IMutableRelation relation) {
super(capacity, ISolution[].class, null/*filter*/);
if (relation == null)
throw new IllegalArgumentException();
this.relation = relation;
}
/**
* Combines chunks of solutions together into a single chunk and then
* delegates to {@link #flush(IChunkedOrderedIterator)}.
*
* Note: Combining chunks together is a huge performance win if the source
* chunks tend to be small (100). For example, this is true for scale-out
* joins such as LUBM U1 EDS. There the performance gain is better than
* 20:1.
*/
@Override
final protected long flush(final int n, final ISolution[][] a) {
final IChunkedOrderedIterator> itr;
/*
* Combine the chunks together.
*/
// count #of elements in all chunks.
int m = 0;
for (int i = 0; i < n; i++) {
m += a[i].length;
}
// allocate perfect fit array.
final ISolution[] b = new ISolution[m];
// combine all elements into a single chunk.
int k = 0;
for (int i = 0; i < n; i++) {
final ISolution[] tmp = a[i];
System.arraycopy(tmp, 0, b, k, tmp.length);
k += tmp.length;
}
// iterator on that single combined chunk.
itr = new ChunkedArrayIterator>(m, b, null/* keyOrder */);
// /*
// * Handle each chunk by itself.
// */
//
// itr = new ChunkConsumerIterator>(
// new ArrayIterator[]>(n, a), null/* keyOrder(unknown)
// */);
return flush(itr);
}
// /**
// *
// * @author Bryan Thompson
// * @version $Id$
// * @param
// */
// private static class ArrayIterator implements ICloseableIterator {
//
// private final int n;
// private final E[] a;
//
// private int i = 0;
//
// public ArrayIterator(int n, E[] a) {
//
// this.n = n;
//
// this.a = a;
//
// }
//
// public void close() {
// // NOP.
// }
//
// public boolean hasNext() {
// return i < n;
// }
//
// public E next() {
// return a[i++];
// }
//
// public void remove() {
// throw new UnsupportedOperationException();
// }
//
// }
/**
* Concrete implementations must process the {@link ISolution}s, causing
* the appropriate mutation on the target {@link IRelation}.
*
* Note: The {@link ISolution}s generally appear in an arbitrary order.
* They can either be resolved to {@link IRelation} elements or be sorted
* into ordered {@link ISolution} chunks using a {@link SolutionComparator}.
*
* @param itr
* The iterator (the order of the elements is unknown).
*
* @return The #of elements that were modified in the backing relation when
* the buffer was flushed
*/
abstract protected long flush(IChunkedOrderedIterator> itr);
/**
* Buffer writes on {@link IMutableRelation#insert(IChunkedIterator)} when it is
* {@link #flush() flushed}.
*
* @author Bryan Thompson
* @version $Id$
* @param
*/
public static class InsertSolutionBuffer extends AbstractSolutionBuffer {
/**
* @param capacity
* @param relation
*/
public InsertSolutionBuffer(int capacity, IMutableRelation relation) {
super(capacity, relation);
}
@Override
protected long flush(IChunkedOrderedIterator> itr) {
final IChunkedOrderedIterator itr2 = new ChunkedResolvingIterator>(
itr) {
@Override
protected E resolve(ISolution e) {
return e.get();
}
};
return getRelation().insert(itr2);
}
}
/**
* Buffer writes on {@link IMutableRelation#delete(IChunkedOrderedIterator)} when it is
* {@link #flush() flushed}.
*
* @author Bryan Thompson
* @version $Id$
* @param
*/
public static class DeleteSolutionBuffer extends AbstractSolutionBuffer {
/**
* @param capacity
* @param relation
*/
public DeleteSolutionBuffer(int capacity, IMutableRelation relation) {
super(capacity,relation);
}
@Override
protected long flush(IChunkedOrderedIterator> itr) {
// final IChunkedOrderedIterator itr2 = new ChunkedOrderedStriterator(
// itr)
// .addFilter(new com.bigdata.striterator.Resolver>, ISolution, E>() {
//
// protected E resolve(ISolution e) {
//
// return e.get();
//
// }
// });
final IChunkedOrderedIterator itr2 = new ChunkedResolvingIterator>(
itr) {
@Override
protected E resolve(ISolution e) {
return e.get();
}
};
return getRelation().delete( itr2 );
}
}
// /**
// * Buffer writes on
// * {@link IMutableRelation#update(IChunkedOrderedIterator, ITransform)} when it is
// * {@link #flush() flushed}.
// *
// * @author Bryan Thompson
// * @version $Id$
// * @param
// */
// public static class UpdateSolutionBuffer extends
// AbstractSolutionBuffer {
//
// private final ITransform transform;
//
// /**
// * @param capacity
// * @param relation
// */
// public UpdateSolutionBuffer(int capacity, IMutableRelation relation,
// ITransform transform) {
//
// super(capacity, relation);
//
// if (transform == null)
// throw new IllegalArgumentException();
//
// this.transform = transform;
//
// }
//
// @Override
// protected long flush(IChunkedOrderedIterator> itr) {
//
// final IChunkedOrderedIterator itr2 = new ChunkedResolvingIterator>(
// itr) {
//
// @Override
// protected E resolve(ISolution e) {
//
// return e.get();
//
// }
//
// };
//
// return getRelation().update(itr2, transform);
//
// }
//
// }
}