use of org.apache.cassandra.index.sasi.utils.RangeIterator in project cassandra by apache.
the class TermIterator method build.
@SuppressWarnings("resource")
public static TermIterator build(final Expression e, Set<SSTableIndex> perSSTableIndexes) {
final List<RangeIterator<Long, Token>> tokens = new CopyOnWriteArrayList<>();
final AtomicLong tokenCount = new AtomicLong(0);
RangeIterator<Long, Token> memtableIterator = e.index.searchMemtable(e);
if (memtableIterator != null) {
tokens.add(memtableIterator);
tokenCount.addAndGet(memtableIterator.getCount());
}
final Set<SSTableIndex> referencedIndexes = new CopyOnWriteArraySet<>();
try {
final CountDownLatch latch = new CountDownLatch(perSSTableIndexes.size());
final ExecutorService searchExecutor = SEARCH_EXECUTOR.get();
for (final SSTableIndex index : perSSTableIndexes) {
if (e.getOp() == Expression.Op.PREFIX && index.mode() == OnDiskIndexBuilder.Mode.CONTAINS && !index.hasMarkedPartials())
throw new UnsupportedOperationException(String.format("The index %s has not yet been upgraded " + "to support prefix queries in CONTAINS mode. " + "Wait for compaction or rebuild the index.", index.getPath()));
if (!index.reference()) {
latch.countDown();
continue;
}
// add to referenced right after the reference was acquired,
// that helps to release index if something goes bad inside of the search
referencedIndexes.add(index);
searchExecutor.submit((Runnable) () -> {
try {
e.checkpoint();
RangeIterator<Long, Token> keyIterator = index.search(e);
if (keyIterator == null) {
releaseIndex(referencedIndexes, index);
return;
}
tokens.add(keyIterator);
tokenCount.getAndAdd(keyIterator.getCount());
} catch (Throwable e1) {
releaseIndex(referencedIndexes, index);
if (logger.isDebugEnabled())
logger.debug(String.format("Failed search an index %s, skipping.", index.getPath()), e1);
} finally {
latch.countDown();
}
});
}
Uninterruptibles.awaitUninterruptibly(latch);
// checkpoint right away after all indexes complete search because we might have crossed the quota
e.checkpoint();
RangeIterator<Long, Token> ranges = RangeUnionIterator.build(tokens);
return new TermIterator(e, ranges, referencedIndexes);
} catch (Throwable ex) {
// if execution quota was exceeded while opening indexes or something else happened
// local (yet to be tracked) indexes should be released first before re-throwing exception
referencedIndexes.forEach(TermIterator::releaseQuietly);
throw ex;
}
}
use of org.apache.cassandra.index.sasi.utils.RangeIterator in project cassandra by apache.
the class ColumnIndex method searchMemtable.
public RangeIterator<Long, Token> searchMemtable(Expression e) {
RangeIterator.Builder<Long, Token> builder = new RangeUnionIterator.Builder<>();
builder.add(getCurrentMemtable().search(e));
for (IndexMemtable memtable : getPendingMemtables()) builder.add(memtable.search(e));
return builder.build();
}
use of org.apache.cassandra.index.sasi.utils.RangeIterator in project cassandra by apache.
the class SkipListMemIndex method search.
public RangeIterator<Long, Token> search(Expression expression) {
ByteBuffer min = expression.lower == null ? null : expression.lower.value;
ByteBuffer max = expression.upper == null ? null : expression.upper.value;
SortedMap<ByteBuffer, ConcurrentSkipListSet<DecoratedKey>> search;
if (min == null && max == null) {
throw new IllegalArgumentException();
}
if (min != null && max != null) {
search = index.subMap(min, expression.lower.inclusive, max, expression.upper.inclusive);
} else if (min == null) {
search = index.headMap(max, expression.upper.inclusive);
} else {
search = index.tailMap(min, expression.lower.inclusive);
}
RangeUnionIterator.Builder<Long, Token> builder = RangeUnionIterator.builder();
search.values().stream().filter(keys -> !keys.isEmpty()).forEach(keys -> builder.add(new KeyRangeIterator(keys)));
return builder.build();
}
use of org.apache.cassandra.index.sasi.utils.RangeIterator in project cassandra by apache.
the class TokenTreeTest method testMergingOfEqualTokenTrees.
public void testMergingOfEqualTokenTrees(SortedMap<Long, LongSet> tokensMap) throws Exception {
TokenTreeBuilder tokensA = new DynamicTokenTreeBuilder(tokensMap);
TokenTreeBuilder tokensB = new DynamicTokenTreeBuilder(tokensMap);
TokenTree a = buildTree(tokensA);
TokenTree b = buildTree(tokensB);
TokenTreeBuilder tokensC = new StaticTokenTreeBuilder(new CombinedTerm(null, null) {
public RangeIterator<Long, Token> getTokenIterator() {
RangeIterator.Builder<Long, Token> union = RangeUnionIterator.builder();
union.add(a.iterator(new KeyConverter()));
union.add(b.iterator(new KeyConverter()));
return union.build();
}
});
TokenTree c = buildTree(tokensC);
Assert.assertEquals(tokensMap.size(), c.getCount());
Iterator<Token> tokenIterator = c.iterator(KEY_CONVERTER);
Iterator<Map.Entry<Long, LongSet>> listIterator = tokensMap.entrySet().iterator();
while (tokenIterator.hasNext() && listIterator.hasNext()) {
Token treeNext = tokenIterator.next();
Map.Entry<Long, LongSet> listNext = listIterator.next();
Assert.assertEquals(listNext.getKey(), treeNext.get());
Assert.assertEquals(convert(listNext.getValue()), convert(treeNext));
}
for (Map.Entry<Long, LongSet> entry : tokensMap.entrySet()) {
TokenTree.OnDiskToken result = c.get(entry.getKey(), KEY_CONVERTER);
Assert.assertNotNull("failed to find object for token " + entry.getKey(), result);
LongSet found = result.getOffsets();
Assert.assertEquals(entry.getValue(), found);
}
}
Aggregations