use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class MetadataDataset method getMetadata.
/**
* Returns metadata for a given set of entities
*
* @param targetIds entities for which metadata is required
* @return map of entitiyId to set of metadata for that entity
*/
public Set<Metadata> getMetadata(Set<? extends NamespacedEntityId> targetIds) {
if (targetIds.isEmpty()) {
return Collections.emptySet();
}
List<ImmutablePair<byte[], byte[]>> fuzzyKeys = new ArrayList<>(targetIds.size());
for (NamespacedEntityId targetId : targetIds) {
fuzzyKeys.add(getFuzzyKeyFor(targetId));
}
// Sort fuzzy keys
Collections.sort(fuzzyKeys, FUZZY_KEY_COMPARATOR);
// Scan using fuzzy filter. Scan returns one row per property.
// Group the rows on namespacedId
Multimap<NamespacedEntityId, MetadataEntry> metadataMap = HashMultimap.create();
byte[] start = fuzzyKeys.get(0).getFirst();
byte[] end = Bytes.stopKeyForPrefix(fuzzyKeys.get(fuzzyKeys.size() - 1).getFirst());
try (Scanner scan = indexedTable.scan(new Scan(start, end, new FuzzyRowFilter(fuzzyKeys)))) {
Row next;
while ((next = scan.next()) != null) {
MetadataEntry metadataEntry = convertRow(next);
if (metadataEntry != null) {
metadataMap.put(metadataEntry.getTargetId(), metadataEntry);
}
}
}
// Create metadata objects for each entity from grouped rows
Set<Metadata> metadataSet = new HashSet<>();
for (Map.Entry<NamespacedEntityId, Collection<MetadataEntry>> entry : metadataMap.asMap().entrySet()) {
Map<String, String> properties = new HashMap<>();
Set<String> tags = Collections.emptySet();
for (MetadataEntry metadataEntry : entry.getValue()) {
if (TAGS_KEY.equals(metadataEntry.getKey())) {
tags = splitTags(metadataEntry.getValue());
} else {
properties.put(metadataEntry.getKey(), metadataEntry.getValue());
}
}
metadataSet.add(new Metadata(entry.getKey(), properties, tags));
}
return metadataSet;
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class MetadataDataset method getMetadata.
/**
* Return metadata based on target id, and key.
*
* @param targetId The id of the target
* @param key The metadata key to get
* @return instance of {@link MetadataEntry} for the target type, id, and key
*/
@Nullable
private MetadataEntry getMetadata(NamespacedEntityId targetId, String key) {
MDSKey mdsKey = MdsKey.getMDSValueKey(targetId, key);
Row row = indexedTable.get(mdsKey.getKey());
if (row.isEmpty()) {
return null;
}
byte[] value = row.get(VALUE_COLUMN);
if (value == null) {
// This can happen when all tags are moved one by one. The row still exists, but the value is null.
return null;
}
return new MetadataEntry(targetId, key, Bytes.toString(value));
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class MetadataDataset method rebuildIndexes.
/**
* Rebuilds all the indexes in the {@link MetadataDataset} in batches.
*
* @param startRowKey the key of the row to start the scan for the current batch with
* @param limit the batch size
* @return the row key of the last row scanned in the current batch, {@code null} if there are no more rows to scan.
*/
@Nullable
public byte[] rebuildIndexes(@Nullable byte[] startRowKey, int limit) {
// Now rebuild indexes for all values in the metadata dataset
byte[] valueRowPrefix = MdsKey.getValueRowPrefix();
// If startRow is null, start at the beginning, else start at the provided start row
startRowKey = startRowKey == null ? valueRowPrefix : startRowKey;
// stopRowKey will always be the last row key with the valueRowPrefix
byte[] stopRowKey = Bytes.stopKeyForPrefix(valueRowPrefix);
Row row;
try (Scanner scanner = indexedTable.scan(startRowKey, stopRowKey)) {
while ((limit > 0) && (row = scanner.next()) != null) {
byte[] rowKey = row.getRow();
String targetType = MdsKey.getTargetType(rowKey);
NamespacedEntityId namespacedEntityId = MdsKey.getNamespacedIdFromKey(targetType, rowKey);
String metadataKey = MdsKey.getMetadataKey(targetType, rowKey);
Set<Indexer> indexers = getIndexersForKey(metadataKey);
MetadataEntry metadataEntry = getMetadata(namespacedEntityId, metadataKey);
if (metadataEntry == null) {
LOG.warn("Found null metadata entry for a known metadata key {} for entity {} which has an index stored. " + "Ignoring.", metadataKey, namespacedEntityId);
continue;
}
// storeIndexes deletes old indexes
storeIndexes(namespacedEntityId, metadataKey, indexers, metadataEntry);
limit--;
}
Row startRowForNextBatch = scanner.next();
if (startRowForNextBatch == null) {
return null;
}
return startRowForNextBatch.getRow();
}
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class MetadataDataset method getMetadata.
/**
* Retrieves the metadata for the specified {@link NamespacedEntityId}.
*
* @param targetId the specified {@link NamespacedEntityId}
* @return a Map representing the metadata for the specified {@link NamespacedEntityId}
*/
private Map<String, String> getMetadata(NamespacedEntityId targetId) {
String targetType = EntityIdKeyHelper.getTargetType(targetId);
MDSKey mdsKey = MdsKey.getMDSValueKey(targetId, null);
byte[] startKey = mdsKey.getKey();
byte[] stopKey = Bytes.stopKeyForPrefix(startKey);
Map<String, String> metadata = new HashMap<>();
try (Scanner scan = indexedTable.scan(startKey, stopKey)) {
Row next;
while ((next = scan.next()) != null) {
String key = MdsKey.getMetadataKey(targetType, next.getRow());
byte[] value = next.get(VALUE_COLUMN);
if (key == null || value == null) {
continue;
}
metadata.put(key, Bytes.toString(value));
}
return metadata;
}
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class MetadataDataset method searchByDefaultIndex.
private SearchResults searchByDefaultIndex(String namespaceId, String searchQuery, Set<EntityTypeSimpleName> types, boolean showHidden, Set<EntityScope> entityScope) {
List<MetadataEntry> results = new LinkedList<>();
for (String searchTerm : getSearchTerms(namespaceId, searchQuery, entityScope)) {
Scanner scanner;
if (searchTerm.endsWith("*")) {
// if prefixed search get start and stop key
byte[] startKey = Bytes.toBytes(searchTerm.substring(0, searchTerm.lastIndexOf("*")));
byte[] stopKey = Bytes.stopKeyForPrefix(startKey);
scanner = indexedTable.scanByIndex(Bytes.toBytes(DEFAULT_INDEX_COLUMN), startKey, stopKey);
} else {
byte[] value = Bytes.toBytes(searchTerm);
scanner = indexedTable.readByIndex(Bytes.toBytes(DEFAULT_INDEX_COLUMN), value);
}
try {
Row next;
while ((next = scanner.next()) != null) {
Optional<MetadataEntry> metadataEntry = parseRow(next, DEFAULT_INDEX_COLUMN, types, showHidden);
if (metadataEntry.isPresent()) {
results.add(metadataEntry.get());
}
}
} finally {
scanner.close();
}
}
// cursors are currently not supported for default indexes
return new SearchResults(results, Collections.<String>emptyList());
}
Aggregations