use of com.google.common.annotations.VisibleForTesting in project cassandra by apache.
the class CompactionManager method getSSTablesToValidate.
@VisibleForTesting
synchronized Refs<SSTableReader> getSSTablesToValidate(ColumnFamilyStore cfs, Validator validator) {
Refs<SSTableReader> sstables;
ActiveRepairService.ParentRepairSession prs = ActiveRepairService.instance.getParentRepairSession(validator.desc.parentSessionId);
if (prs == null)
return null;
Set<SSTableReader> sstablesToValidate = new HashSet<>();
com.google.common.base.Predicate<SSTableReader> predicate;
if (validator.isConsistent) {
predicate = s -> validator.desc.parentSessionId.equals(s.getSSTableMetadata().pendingRepair);
} else {
// note that we always grab all existing sstables for this - if we were to just grab the ones that
// were marked as repairing, we would miss any ranges that were compacted away and this would cause us to overstream
predicate = (s) -> !prs.isIncremental || !s.isRepaired();
}
try (ColumnFamilyStore.RefViewFragment sstableCandidates = cfs.selectAndReference(View.select(SSTableSet.CANONICAL, predicate))) {
for (SSTableReader sstable : sstableCandidates.sstables) {
if (new Bounds<>(sstable.first.getToken(), sstable.last.getToken()).intersects(validator.desc.ranges)) {
sstablesToValidate.add(sstable);
}
}
sstables = Refs.tryRef(sstablesToValidate);
if (sstables == null) {
logger.error("Could not reference sstables");
throw new RuntimeException("Could not reference sstables");
}
}
return sstables;
}
use of com.google.common.annotations.VisibleForTesting in project cassandra by apache.
the class Operation method analyzeGroup.
@VisibleForTesting
protected static ListMultimap<ColumnMetadata, Expression> analyzeGroup(QueryController controller, OperationType op, List<RowFilter.Expression> expressions) {
ListMultimap<ColumnMetadata, Expression> analyzed = ArrayListMultimap.create();
// sort all of the expressions in the operation by name and priority of the logical operator
// this gives us an efficient way to handle inequality and combining into ranges without extra processing
// and converting expressions from one type to another.
Collections.sort(expressions, (a, b) -> {
int cmp = a.column().compareTo(b.column());
return cmp == 0 ? -Integer.compare(getPriority(a.operator()), getPriority(b.operator())) : cmp;
});
for (final RowFilter.Expression e : expressions) {
ColumnIndex columnIndex = controller.getIndex(e);
List<Expression> perColumn = analyzed.get(e.column());
if (columnIndex == null)
columnIndex = new ColumnIndex(controller.getKeyValidator(), e.column(), null);
AbstractAnalyzer analyzer = columnIndex.getAnalyzer();
analyzer.reset(e.getIndexValue());
// EQ/LIKE_*/NOT_EQ can have multiple expressions e.g. text = "Hello World",
// becomes text = "Hello" OR text = "World" because "space" is always interpreted as a split point (by analyzer),
// NOT_EQ is made an independent expression only in case of pre-existing multiple EQ expressions, or
// if there is no EQ operations and NOT_EQ is met or a single NOT_EQ expression present,
// in such case we know exactly that there would be no more EQ/RANGE expressions for given column
// since NOT_EQ has the lowest priority.
boolean isMultiExpression = false;
switch(e.operator()) {
case EQ:
isMultiExpression = false;
break;
case LIKE_PREFIX:
case LIKE_SUFFIX:
case LIKE_CONTAINS:
case LIKE_MATCHES:
isMultiExpression = true;
break;
case NEQ:
isMultiExpression = (perColumn.size() == 0 || perColumn.size() > 1 || (perColumn.size() == 1 && perColumn.get(0).getOp() == Op.NOT_EQ));
break;
}
if (isMultiExpression) {
while (analyzer.hasNext()) {
final ByteBuffer token = analyzer.next();
perColumn.add(new Expression(controller, columnIndex).add(e.operator(), token));
}
} else // "range" or not-equals operator, combines both bounds together into the single expression,
// iff operation of the group is AND, otherwise we are forced to create separate expressions,
// not-equals is combined with the range iff operator is AND.
{
Expression range;
if (perColumn.size() == 0 || op != OperationType.AND)
perColumn.add((range = new Expression(controller, columnIndex)));
else
range = Iterables.getLast(perColumn);
while (analyzer.hasNext()) range.add(e.operator(), analyzer.next());
}
}
return analyzed;
}
use of com.google.common.annotations.VisibleForTesting in project cassandra by apache.
the class OnDiskIndexBuilder method finish.
@VisibleForTesting
protected boolean finish(Descriptor descriptor, File file) throws FSWriteError {
// no terms means there is nothing to build
if (terms.isEmpty())
return false;
// split terms into suffixes only if it's text, otherwise (even if CONTAINS is set) use terms in original form
SA sa = ((termComparator instanceof UTF8Type || termComparator instanceof AsciiType) && mode == Mode.CONTAINS) ? new SuffixSA(termComparator, mode) : new IntegralSA(termComparator, mode);
for (Map.Entry<ByteBuffer, TokenTreeBuilder> term : terms.entrySet()) sa.add(term.getKey(), term.getValue());
finish(descriptor, Pair.create(minKey, maxKey), file, sa.finish());
return true;
}
use of com.google.common.annotations.VisibleForTesting in project cassandra by apache.
the class StreamSession method getSSTableSectionsForRanges.
@VisibleForTesting
public static List<SSTableStreamingSections> getSSTableSectionsForRanges(Collection<Range<Token>> ranges, Collection<ColumnFamilyStore> stores, long overriddenRepairedAt, UUID pendingRepair) {
Refs<SSTableReader> refs = new Refs<>();
try {
for (ColumnFamilyStore cfStore : stores) {
final List<Range<PartitionPosition>> keyRanges = new ArrayList<>(ranges.size());
for (Range<Token> range : ranges) keyRanges.add(Range.makeRowRange(range));
refs.addAll(cfStore.selectAndReference(view -> {
Set<SSTableReader> sstables = Sets.newHashSet();
SSTableIntervalTree intervalTree = SSTableIntervalTree.build(view.select(SSTableSet.CANONICAL));
Predicate<SSTableReader> predicate;
if (pendingRepair == ActiveRepairService.NO_PENDING_REPAIR) {
predicate = Predicates.alwaysTrue();
} else {
predicate = s -> s.isPendingRepair() && s.getSSTableMetadata().pendingRepair.equals(pendingRepair);
}
for (Range<PartitionPosition> keyRange : keyRanges) {
for (SSTableReader sstable : Iterables.filter(View.sstablesInBounds(keyRange.left, keyRange.right, intervalTree), predicate)) {
sstables.add(sstable);
}
}
if (logger.isDebugEnabled())
logger.debug("ViewFilter for {}/{} sstables", sstables.size(), Iterables.size(view.select(SSTableSet.CANONICAL)));
return sstables;
}).refs);
}
List<SSTableStreamingSections> sections = new ArrayList<>(refs.size());
for (SSTableReader sstable : refs) {
long repairedAt = overriddenRepairedAt;
if (overriddenRepairedAt == ActiveRepairService.UNREPAIRED_SSTABLE)
repairedAt = sstable.getSSTableMetadata().repairedAt;
sections.add(new SSTableStreamingSections(refs.get(sstable), sstable.getPositionsForRanges(ranges), sstable.estimatedKeysForRanges(ranges), repairedAt));
}
return sections;
} catch (Throwable t) {
refs.release();
throw t;
}
}
use of com.google.common.annotations.VisibleForTesting in project cassandra by apache.
the class MerkleTrees method hash.
@VisibleForTesting
public byte[] hash(Range<Token> range) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean hashed = false;
try {
for (Range<Token> rt : merkleTrees.keySet()) {
if (rt.intersects(range)) {
byte[] bytes = merkleTrees.get(rt).hash(range);
if (bytes != null) {
baos.write(bytes);
hashed = true;
}
}
}
} catch (IOException e) {
throw new RuntimeException("Unable to append merkle tree hash to result");
}
return hashed ? baos.toByteArray() : null;
}
Aggregations