com.netflix.astyanax.model.Row Java Examples

The following examples show how to use com.netflix.astyanax.model.Row. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CassandraArchiveRepository.java    From Nicobar with Apache License 2.0 6 votes vote down vote up
/**
 * Get a summary of all archives in this Repository
 * @return List of summaries
 */
@Override
public List<ArchiveSummary> getArchiveSummaries() throws IOException {
    List<ArchiveSummary> summaries = new LinkedList<ArchiveSummary>();
    Iterable<Row<String, String>> rows;
    try {
            rows = getRows((EnumSet<?>)EnumSet.of(Columns.module_id, Columns.last_update, Columns.module_spec));
    } catch (Exception e) {
        throw new IOException(e);
    }

    for (Row<String, String> row : rows) {
        String moduleId = row.getKey();
        ColumnList<String> columns = row.getColumns();
        Column<String> lastUpdateColumn = columns.getColumnByName(Columns.last_update.name());
        long updateTime = lastUpdateColumn != null ? lastUpdateColumn.getLongValue() : 0;
        ScriptModuleSpec moduleSpec = getModuleSpec(columns);
        ArchiveSummary summary = new ArchiveSummary(ModuleId.fromString(moduleId), moduleSpec, updateTime, null);
        summaries.add(summary);
    }
    return summaries;
}
 
Example #2
Source File: CassandraArchiveRepository.java    From Nicobar with Apache License 2.0 6 votes vote down vote up
/**
 * Get the last update times of all of the script archives managed by this Repository.
 * @return map of moduleId to last update time
 */
@Override
public Map<ModuleId, Long> getArchiveUpdateTimes() throws IOException {
    Iterable<Row<String, String>> rows;
    try {
        rows = getRows((EnumSet<?>)EnumSet.of(Columns.module_id, Columns.last_update));
    } catch (Exception e) {
        throw new IOException(e);
    }
    Map<ModuleId, Long> updateTimes = new LinkedHashMap<ModuleId, Long>();
    for (Row<String, String> row : rows) {
        String moduleId = row.getKey();
        Column<String> lastUpdateColumn = row.getColumns().getColumnByName(Columns.last_update.name());
        Long updateTime = lastUpdateColumn != null ? lastUpdateColumn.getLongValue() : null;
        if (StringUtils.isNotBlank(moduleId) && updateTime != null) {
            updateTimes.put(ModuleId.fromString(moduleId), updateTime);
        }
    }
    return updateTimes;
}
 
Example #3
Source File: CassandraArchiveRepository.java    From Nicobar with Apache License 2.0 6 votes vote down vote up
/**
 * Get all of the rows in in the table. Attempts to reduce the load on cassandra by splitting up the query into smaller sub-queries
 * @param columns which columns to select
 * @return result rows
 */
protected Iterable<Row<String, String>> getRows(EnumSet<?> columns) throws Exception {
    int shardCount = config.getShardCount();

    List<Future<Rows<String, String>>> futures = new ArrayList<Future<Rows<String, String>>>();
    for (int i = 0; i < shardCount; i++) {
        futures.add(cassandra.selectAsync(generateSelectByShardCql(columns, i)));
    }

    List<Row<String, String>> rows = new LinkedList<Row<String, String>>();
    for (Future<Rows<String, String>> f: futures) {
        Rows<String, String> shardRows = f.get();
        Iterables.addAll(rows, shardRows);
    }

    return rows;
}
 
Example #4
Source File: AstyanaxQueueDAO.java    From emodb with Apache License 2.0 6 votes vote down vote up
@Override
public Iterator<String> listQueues() {
    final Iterator<Row<String, UUID>> rowIter = execute(
            _keyspace.prepareQuery(CF_DEDUP_MD, ConsistencyLevel.CL_LOCAL_QUORUM)
                    .getAllRows()
                    .setRowLimit(100)
                    .withColumnRange(new RangeBuilder().setLimit(1).build()))
            .iterator();
    return new AbstractIterator<String>() {
        @Override
        protected String computeNext() {
            while (rowIter.hasNext()) {
                Row<String, UUID> row = rowIter.next();
                if (!row.getColumns().isEmpty()) {
                    return row.getKey();
                }
            }
            return endOfData();
        }
    };
}
 
Example #5
Source File: AstyanaxQueueDAO.java    From emodb with Apache License 2.0 6 votes vote down vote up
@Override
public Map<UUID, ByteBuffer> findMaxRecords(Collection<UUID> dataIds) {
    // Finding the max using a reversed column range shouldn't have to worry about skipping tombstones since
    // we always delete smaller column values before deleting larger column values--scanning will hit the max
    // before needing to skip over tombstones.
    Map<UUID, ByteBuffer> resultMap = Maps.newHashMap();
    for (List<UUID> batch : Iterables.partition(dataIds, 10)) {
        Rows<UUID, ByteBuffer> rows = execute(
                _keyspace.prepareQuery(CF_DEDUP_DATA, ConsistencyLevel.CL_LOCAL_QUORUM)
                        .getKeySlice(batch)
                        .withColumnRange(new RangeBuilder()
                                .setReversed(true)
                                .setLimit(1)
                                .build()));
        for (Row<UUID, ByteBuffer> row : rows) {
            UUID dataId = row.getKey();
            for (Column<ByteBuffer> column : row.getColumns()) {
                resultMap.put(dataId, column.getName());
            }
        }
    }
    return resultMap;
}
 
Example #6
Source File: AstyanaxEventReaderDAO.java    From emodb with Apache License 2.0 6 votes vote down vote up
@Override
public Iterator<String> listChannels() {
    final Iterator<Row<String, ByteBuffer>> rowIter = execute(
            _keyspace.prepareQuery(ColumnFamilies.MANIFEST, ConsistencyLevel.CL_LOCAL_QUORUM)
                    .getAllRows()
                    .setRowLimit(1000)
                    .withColumnRange(new RangeBuilder().setLimit(1).build()))
            .iterator();
    return new AbstractIterator<String>() {
        @Override
        protected String computeNext() {
            while (rowIter.hasNext()) {
                Row<String, ByteBuffer> row = rowIter.next();
                if (!row.getColumns().isEmpty()) {
                    return row.getKey();
                }
            }
            return endOfData();
        }
    };
}
 
Example #7
Source File: AstyanaxBlockedDataReaderDAO.java    From emodb with Apache License 2.0 6 votes vote down vote up
@Override
public Iterator<? extends MigrationScanResult> getDeltasForStorage(AstyanaxStorage source) {
    DeltaPlacement sourcePlacement = (DeltaPlacement) source.getPlacement();
    ColumnFamily<ByteBuffer, DeltaKey> sourceCf = sourcePlacement.getBlockedDeltaColumnFamily();

    Iterator<ByteBufferRange> scanIter = source.scanIterator(null);

    return Iterators.concat(Iterators.transform(scanIter, keyRange -> {
        Iterator<Row<ByteBuffer, DeltaKey>> rows =
                rowScan(sourcePlacement, sourceCf, keyRange, _maxColumnsRange, LimitCounter.max(), ReadConsistency.STRONG);

        return Iterators.concat(Iterators.transform(rows, row -> {
            ColumnList<DeltaKey> columns = row.getColumns();
            Iterator<Column<DeltaKey>> concatColumns = columns.iterator();
            if (columns.size() >= _maxColumnsRange.getLimit()) {
                DeltaKey lastColumn = row.getColumns().getColumnByIndex(columns.size() - 1).getName();
                concatColumns = Iterators.concat(concatColumns, columnScan(row.getRawKey(), sourcePlacement, sourceCf, lastColumn, null,
                        false, _deltaKeyInc, Long.MAX_VALUE, 1, ReadConsistency.STRONG));
            }

            Iterator<StitchedColumn> uuidColumns = new AstyanaxDeltaIterator(concatColumns, false, _deltaPrefixLength, ByteBufferUtil.bytesToHex(row.getRawKey()));

            return Iterators.transform(uuidColumns, column -> new MigrationScanResult(row.getRawKey(), column.getName(), _daoUtils.skipPrefix(column.getByteBufferValue())));
        }));
    }));
}
 
Example #8
Source File: AstyanaxBlockedDataReaderDAO.java    From emodb with Apache License 2.0 6 votes vote down vote up
@Override
public Iterator<? extends HistoryMigrationScanResult> getHistoriesForStorage(AstyanaxStorage source) {

    DeltaPlacement placement = (DeltaPlacement) source.getPlacement();
    ColumnFamily<ByteBuffer, UUID> cf = placement.getDeltaHistoryColumnFamily();

    return Iterators.concat(Iterators.transform(source.scanIterator(null), keyRange -> {
        Iterator<Row<ByteBuffer, UUID>> rows =
                rowScan(placement, cf, keyRange, _maxColumnsRange, LimitCounter.max(), ReadConsistency.STRONG);

        return Iterators.concat(Iterators.transform(rows, row -> {
            ColumnList<UUID> columns = row.getColumns();
            Iterator<Column<UUID>> concatColumns = columns.iterator();
            if (columns.size() >= _maxColumnsRange.getLimit()) {
                UUID lastColumn = row.getColumns().getColumnByIndex(columns.size() - 1).getName();
                concatColumns = Iterators.concat(concatColumns, columnScan(row.getRawKey(), placement, cf, lastColumn, null,
                        false, _uuidInc, Long.MAX_VALUE, 1, ReadConsistency.STRONG));
            }
            return Iterators.transform(concatColumns, column -> new HistoryMigrationScanResult(row.getRawKey(), column.getName(), column.getByteBufferValue(), column.getTtl()));
        }));
    }));
}
 
Example #9
Source File: AstyanaxDao.java    From staash with Apache License 2.0 6 votes vote down vote up
@Override
public Collection<String> listIds() throws PersistenceException {
    final List<String> ids = Lists.newArrayList();
    try {
        new AllRowsReader.Builder<String, String>(keyspace, columnFamily)
            .withIncludeEmptyRows(false)
            .forEachRow(new Function<Row<String,String>, Boolean>() {
                @Override
                public Boolean apply(Row<String, String> row) {
                    ids.add(row.getKey());
                    return true;
                }
            })
            .build()
            .call();
    } catch (Exception e) {
        throw new PersistenceException("Error trying to fetch row ids", e);
    }
        
    return ids;
}
 
Example #10
Source File: AstyanaxBlockedDataReaderDAO.java    From emodb with Apache License 2.0 6 votes vote down vote up
/**
 * Decodes rows returned by querying for a specific set of rows.
 */
private Iterator<Record> decodeRows(List<Map.Entry<ByteBuffer, Key>> keys, final Rows<ByteBuffer, DeltaKey> rows,
                                    final int largeRowThreshold, final ReadConsistency consistency) {
    // Avoiding pinning multiple decoded rows into memory at once.
    return Iterators.transform(keys.iterator(), new Function<Map.Entry<ByteBuffer, Key>, Record>() {
        @Override
        public Record apply(Map.Entry<ByteBuffer, Key> entry) {
            Row<ByteBuffer, DeltaKey> row = rows.getRow(entry.getKey());
            if (row == null) {
                return emptyRecord(entry.getValue());
            }
            // Convert the results into a Record object, lazily fetching the rest of the columns as necessary.
            return newRecord(entry.getValue(), row.getRawKey(), row.getColumns(), largeRowThreshold, consistency, null);
        }
    });
}
 
Example #11
Source File: CassandraArchiveRepositoryTest.java    From Nicobar with Apache License 2.0 5 votes vote down vote up
@Test
@SuppressWarnings("unchecked")
public void testGetRows() throws Exception {
    EnumSet<Columns> columns = EnumSet.of(Columns.module_id, Columns.module_name);
    Rows<String, String> mockRows = mock(Rows.class);
    Row<String, String> row1 = mock(Row.class);
    Row<String, String> row2 = mock(Row.class);
    List<Row<String, String>> rowList = Arrays.asList(row1, row2);

    when(mockRows.iterator()).thenReturn(rowList.iterator());

    FutureTask<Rows<String, String>> future = new FutureTask<Rows<String, String>>(new Runnable() {
        @Override
        public void run() {
        }
    }, mockRows);
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.execute(future);
    when(gateway.selectAsync(anyString())).thenReturn(future);

    repository.getRows(columns);
    List<String> selectList = new ArrayList<String>();
    for (int shardNum = 0; shardNum < config.getShardCount(); shardNum++) {
        selectList.add(repository.generateSelectByShardCql(columns, shardNum));
    }

    InOrder inOrder = inOrder(gateway);
    for (int shardNum = 0; shardNum < config.getShardCount(); shardNum++) {
        inOrder.verify(gateway).selectAsync(selectList.get(shardNum));
    }
}
 
Example #12
Source File: CassandraStorage.java    From greycat with Apache License 2.0 5 votes vote down vote up
@Override
public void get(Buffer keys, Callback<Buffer> callback) {
    try {
        BufferIterator it = keys.iterator();
        final List<byte[]> all_keys = new ArrayList<byte[]>();
        final Map<byte[], byte[]> results = new HashMap<byte[], byte[]>();
        while (it.hasNext()) {
            Buffer keyView = it.next();
            if (keyView != null) {
                all_keys.add(keyView.data());
            }
        }
        Rows<byte[], Integer> rows = keyspace.prepareQuery(MWG).getKeySlice(all_keys).execute().getResult();
        for (int i = 0; i < rows.size(); i++) {
            Row<byte[], Integer> row = rows.getRowByIndex(i);
            if(row != null){
                Column col = row.getColumns().getColumnByName(0);
                if(col != null){
                    results.put(row.getKey(), col.getByteArrayValue());
                }
            }
        }
        Buffer result = graph.newBuffer();
        for (int i = 0; i < all_keys.size(); i++) {
            if (i != 0) {
                result.write(Constants.BUFFER_SEP);
            }
            byte[] resolved = results.get(all_keys.get(i));
            if(resolved != null){
                result.writeAll(resolved);

            }
        }
        callback.on(result);
    } catch (Exception e) {
        e.printStackTrace();
    }

}
 
Example #13
Source File: AstyanaxThriftDataTableResource.java    From staash with Apache License 2.0 5 votes vote down vote up
@Override
public QueryResult listRows(String cursor, Integer rowLimit, Integer columnLimit) throws PaasException {
    try {
        invariant();
        
        // Execute the query
        Partitioner partitioner = keyspace.getPartitioner();
        Rows<ByteBuffer, ByteBuffer> result = keyspace
            .prepareQuery(columnFamily)
            .getKeyRange(null,  null, cursor != null ? cursor : partitioner.getMinToken(),  partitioner.getMaxToken(),  rowLimit)
            .execute()
            .getResult();
        
        // Convert raw data into a simple sparse tree
        SchemalessRows.Builder builder = SchemalessRows.builder();
        for (Row<ByteBuffer, ByteBuffer> row : result) { 
            Map<String, String> columns = Maps.newHashMap();
            for (Column<ByteBuffer> column : row.getColumns()) {
                columns.put(serializers.columnAsString(column.getRawName()), serializers.valueAsString(column.getRawName(), column.getByteBufferValue()));
            }
            builder.addRow(serializers.keyAsString(row.getKey()), columns);
        }
        
        QueryResult dr = new QueryResult();
        dr.setSrows(builder.build());
        
        if (!result.isEmpty()) {
            dr.setCursor(partitioner.getTokenForKey(Iterables.getLast(result).getKey()));
        }
        return dr;
    } catch (ConnectionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}
 
Example #14
Source File: AstyanaxMetaDaoImpl.java    From staash with Apache License 2.0 5 votes vote down vote up
public Map<String, JsonObject> runQuery(String key, String col) {
	OperationResult<CqlStatementResult> rs;
	Map<String, JsonObject> resultMap = new HashMap<String, JsonObject>();
	try {
		String queryStr = "";
		if (col != null && !col.equals("*")) {
			queryStr = "select column1, value from "+MetaConstants.META_KEY_SPACE + "." + MetaConstants.META_COLUMN_FAMILY +" where key='"
					+ key + "' and column1='" + col + "';";
		} else {
			queryStr = "select column1, value from "+MetaConstants.META_KEY_SPACE + "." + MetaConstants.META_COLUMN_FAMILY +" where key='"
					+ key + "';";
		}
		rs = keyspace.prepareCqlStatement().withCql(queryStr).execute();
		for (Row<String, String> row : rs.getResult().getRows(METACF)) {

			ColumnList<String> columns = row.getColumns();

			String key1 = columns.getStringValue("column1", null);
			String val1 = columns.getStringValue("value", null);
			resultMap.put(key1, new JsonObject(val1));
		}
	} catch (ConnectionException e) {
		e.printStackTrace();
		throw new RuntimeException(e.getMessage());
	}

	return resultMap;
}
 
Example #15
Source File: AstyanaxBlockedDataReaderDAO.java    From emodb with Apache License 2.0 5 votes vote down vote up
/**
 * Decodes rows returned by scanning a table.
 */
private Iterator<Record> decodeRows(Iterator<Row<ByteBuffer, DeltaKey>> iter, final AstyanaxTable table,
                                    final int largeRowThreshold, final ReadConsistency consistency) {
    // Avoiding pinning multiple decoded rows into memory at once.
    return Iterators.transform(iter, new Function<Row<ByteBuffer, DeltaKey>, Record>() {
        @Override
        public Record apply(Row<ByteBuffer, DeltaKey> row) {
            // Convert the results into a Record object, lazily fetching the rest of the columns as necessary.
            String key = AstyanaxStorage.getContentKey(row.getRawKey());
            return newRecord(new Key(table, key), row.getRawKey(), row.getColumns(), largeRowThreshold, consistency, null);
        }
    });
}
 
Example #16
Source File: AstyanaxBlockedDataReaderDAO.java    From emodb with Apache License 2.0 5 votes vote down vote up
/**
 * Decodes row keys returned by scanning a table.
 */
private Iterator<String> decodeKeys(final Iterator<Row<ByteBuffer, DeltaKey>> iter) {
    return new AbstractIterator<String>() {
        @Override
        protected String computeNext() {
            while (iter.hasNext()) {
                Row<ByteBuffer, DeltaKey> row = iter.next();
                if (!row.getColumns().isEmpty()) { // Ignore range ghosts
                    return AstyanaxStorage.getContentKey(row.getRawKey());
                }
            }
            return endOfData();
        }
    };
}
 
Example #17
Source File: AstyanaxBlockedDataReaderDAO.java    From emodb with Apache License 2.0 5 votes vote down vote up
/**
 * Scans for rows within the specified range, exclusive on start and inclusive on end.
 */
private Iterator<Row<ByteBuffer, DeltaKey>> rowScan(final DeltaPlacement placement,
                                                    final ByteBufferRange rowRange,
                                                    final ByteBufferRange columnRange,
                                                    final LimitCounter limit,
                                                    final ReadConsistency consistency) {
    return rowScan(placement, placement.getBlockedDeltaColumnFamily(), rowRange, columnRange, limit, consistency);
}
 
Example #18
Source File: AstyanaxStorageProvider.java    From emodb with Apache License 2.0 5 votes vote down vote up
private long countRowsInColumn(Table tbl, ColumnGroup column) {
    Objects.requireNonNull(tbl, "table");

    AstyanaxTable table = (AstyanaxTable) tbl;
    AstyanaxStorage storage = table.getReadStorage();
    BlobPlacement placement = (BlobPlacement) storage.getPlacement();

    // Limit the # of columns to retrieve since we just want to count rows, but we need one column to ignore range
    // ghosts.
    CompositeSerializer colSerializer = CompositeSerializer.get();
    ByteBufferRange columnRange = new RangeBuilder()
            .setStart(getColumnPrefix(column, Composite.ComponentEquality.LESS_THAN_EQUAL), colSerializer)
            .setEnd(getColumnPrefix(column, Composite.ComponentEquality.GREATER_THAN_EQUAL), colSerializer)
            .setLimit(1)
            .build();
    LimitCounter unlimited = LimitCounter.max();

    // Range query all the shards and count the number of rows in each.
    long count = 0;
    Iterator<ByteBufferRange> scanIter = storage.scanIterator(null);
    while (scanIter.hasNext()) {
        ByteBufferRange keyRange = scanIter.next();
        Iterator<Row<ByteBuffer, Composite>> rowIter = scanInternal(placement, keyRange, columnRange, unlimited);
        while (rowIter.hasNext()) {
            if (!rowIter.next().getColumns().isEmpty()) {
                count++;
            }
        }
    }
    return count;
}
 
Example #19
Source File: AstyanaxStorageProvider.java    From emodb with Apache License 2.0 5 votes vote down vote up
private static Iterator<Map.Entry<String, StorageSummary>> decodeMetadataRows(
        final Iterator<Row<ByteBuffer, Composite>> rowIter, final AstyanaxTable table) {
    return new AbstractIterator<Map.Entry<String, StorageSummary>>() {
        @Override
        protected Map.Entry<String, StorageSummary> computeNext() {
            while (rowIter.hasNext()) {
                Row<ByteBuffer, Composite> row = rowIter.next();
                ByteBuffer key = row.getKey();
                ColumnList<Composite> columns = row.getColumns();

                String blobId = AstyanaxStorage.getContentKey(key);

                StorageSummary summary = toStorageSummary(columns);
                if (summary == null) {
                    continue;  // Partial blob, parts may still be replicating.
                }

                // TODO should be removed for blob s3 migration
                // Cleanup older versions of the blob, if any (unlikely).
                deleteDataColumns(table, blobId, columns, ConsistencyLevel.CL_ANY, summary.getTimestamp());

                return Maps.immutableEntry(blobId, summary);
            }
            return endOfData();
        }
    };
}
 
Example #20
Source File: AstyanaxRowCounterFunction.java    From blueflood with Apache License 2.0 4 votes vote down vote up
@Override
public Boolean apply(Row<K,C> input) {
    counter.incrementAndGet();
    return true;
}
 
Example #21
Source File: ACassandraUtilsIO.java    From blueflood with Apache License 2.0 4 votes vote down vote up
@Override
public Boolean apply(Row<K,C> input) {
    counter.incrementAndGet();
    return true;
}
 
Example #22
Source File: NodeSerializationImpl.java    From usergrid with Apache License 2.0 4 votes vote down vote up
@Override
public Map<Id, Long> getMaxVersions( final ApplicationScope scope, final Collection<? extends Edge> edges ) {
    ValidationUtils.validateApplicationScope( scope );
    Preconditions.checkNotNull( edges, "edges cannot be null" );


    final ColumnFamilyQuery<ScopedRowKey< Id>, Boolean> query =
            keyspace.prepareQuery( GRAPH_DELETE ).setConsistencyLevel( fig.getReadCL() );


    final List<ScopedRowKey< Id>> keys =
            new ArrayList<>( edges.size() );

    //worst case all are marked
    final Map<Id, Long> versions = new HashMap<>( edges.size() );

    final Id scopeId = scope.getApplication();

    for ( final Edge edge : edges ) {
        keys.add( ScopedRowKey.fromKey( scopeId, edge.getSourceNode() ) );
        keys.add( ScopedRowKey.fromKey( scopeId, edge.getTargetNode() ) );
    }


    final Rows<ScopedRowKey<Id>, Boolean> results;
    try {
        results = query.getRowSlice( keys ).withColumnSlice( Collections.singletonList( COLUMN_NAME )).execute()
                .getResult();
    }
    catch ( ConnectionException e ) {
        throw new RuntimeException( "Unable to connect to casandra", e );
    }

    for ( Row<ScopedRowKey<Id>, Boolean> row : results ) {
        Column<Boolean> column = row.getColumns().getColumnByName( COLUMN_NAME );

        if ( column != null ) {
            versions.put( row.getKey().getKey(), column.getLongValue() );
        }
    }


    return versions;
}
 
Example #23
Source File: CassandraArchiveRepository.java    From Nicobar with Apache License 2.0 4 votes vote down vote up
/**
 * Get all of the {@link ScriptArchive}s for the given set of moduleIds. Will perform the operation in batches
 * as specified by {@link CassandraArchiveRepositoryConfig#getArchiveFetchBatchSize()} and outputs the jar files in
 * the path specified by {@link CassandraArchiveRepositoryConfig#getArchiveOutputDirectory()}.
 *
 * @param moduleIds keys to search for
 * @return set of ScriptArchives retrieved from the database
 */
@Override
public Set<ScriptArchive> getScriptArchives(Set<ModuleId> moduleIds) throws IOException {
    Set<ScriptArchive> archives = new LinkedHashSet<ScriptArchive>(moduleIds.size()*2);
    Path archiveOuputDir = getConfig().getArchiveOutputDirectory();
    List<ModuleId> moduleIdList = new LinkedList<ModuleId>(moduleIds);
    int batchSize = getConfig().getArchiveFetchBatchSize();
    int start = 0;
    try {
        while (start < moduleIdList.size()) {
            int end = Math.min(moduleIdList.size(), start + batchSize);
            List<ModuleId> batchModuleIds = moduleIdList.subList(start, end);
            List<String> rowKeys = new ArrayList<String>(batchModuleIds.size());
            for (ModuleId batchModuleId:batchModuleIds) {
                rowKeys.add(batchModuleId.toString());
            }

            Rows<String, String> rows = cassandra.getRows(rowKeys.toArray(new String[0]));
            for (Row<String, String> row : rows) {
                String moduleId = row.getKey();
                ColumnList<String> columns = row.getColumns();
                Column<String> lastUpdateColumn = columns.getColumnByName(Columns.last_update.name());
                Column<String> hashColumn = columns.getColumnByName(Columns.archive_content_hash.name());
                Column<String> contentColumn = columns.getColumnByName(Columns.archive_content.name());
                if (lastUpdateColumn == null || hashColumn == null || contentColumn == null) {
                    continue;
                }
                ScriptModuleSpec moduleSpec = getModuleSpec(columns);
                long lastUpdateTime = lastUpdateColumn.getLongValue();
                byte[] hash = hashColumn.getByteArrayValue();
                byte[] content = contentColumn.getByteArrayValue();

                // verify the hash
                if (hash != null && hash.length > 0 && !verifyHash(hash, content)) {
                    logger.warn("Content hash validation failed for moduleId {}. size: {}", moduleId, content.length);
                    continue;
                }
                String fileName = new StringBuilder().append(moduleId).append("-").append(lastUpdateTime).append(".jar").toString();
                Path jarFile = archiveOuputDir.resolve(fileName);
                Files.write(jarFile, content);
                JarScriptArchive scriptArchive = new JarScriptArchive.Builder(jarFile)
                    .setModuleSpec(moduleSpec)
                    .setCreateTime(lastUpdateTime)
                    .build();
                archives.add(scriptArchive);
            }
            start = end;
        }
    } catch (Exception e) {
        throw new IOException(e);
    }
    return archives;
}
 
Example #24
Source File: AstyanaxStorageProvider.java    From emodb with Apache License 2.0 4 votes vote down vote up
/**
 * Queries for rows within the specified range, exclusive on start and inclusive on end.
 */
private Iterator<Row<ByteBuffer, Composite>> scanInternal(final BlobPlacement placement, final ByteBufferRange keyRange,
                                                          final ByteBufferRange columnRange, final LimitCounter limit) {
    return Iterators.concat(new AbstractIterator<Iterator<Row<ByteBuffer, Composite>>>() {
        private ByteBuffer _rangeStart = keyRange.getStart();
        private final ByteBuffer _rangeEnd = keyRange.getEnd();
        private int _minimumLimit = 1;
        private boolean _done;

        @Override
        protected Iterator<Row<ByteBuffer, Composite>> computeNext() {
            // Note: if Cassandra is asked to perform a token range query where start >= end it will wrap
            // around which is absolutely *not* what we want since it could return data for another table.
            if (_done || BufferUtils.compareUnsigned(_rangeStart, _rangeEnd) >= 0) {
                return endOfData();
            }

            Timer.Context timer = _scanBatchTimer.time();
            try {
                int batchSize = (int) Math.min(Math.max(limit.remaining(), _minimumLimit), MAX_SCAN_METADATA_BATCH_SIZE);
                // Increase the minimum limit a bit each time around so if we start encountering lots of range
                // ghosts we eventually scan through them at a reasonable rate.
                _minimumLimit = Math.min(_minimumLimit + 3, MAX_SCAN_METADATA_BATCH_SIZE);

                // Pass token strings to get exclusive start behavior, to support 'fromBlobIdExclusive'.
                Rows<ByteBuffer, Composite> rows = execute(placement.getKeyspace()
                        .prepareQuery(placement.getBlobColumnFamily(), _readConsistency)
                        .getKeyRange(null, null, toTokenString(_rangeStart), toTokenString(_rangeEnd), batchSize)
                        .withColumnRange(columnRange));

                if (rows.size() >= batchSize) {
                    // Save the last row key so we can use it as the start (exclusive) if we must query to get more data.
                    _rangeStart = rows.getRowByIndex(rows.size() - 1).getKey();
                } else {
                    // If we got fewer rows than we asked for, another query won't find more rows.
                    _done = true;
                }

                // Track metrics
                _scanReadMeter.mark(rows.size());

                // Return the rows.  Filter out range ghosts (deleted rows with no columns)
                final Iterator<Row<ByteBuffer, Composite>> rowIter = rows.iterator();
                return new AbstractIterator<Row<ByteBuffer, Composite>>() {
                    @Override
                    protected Row<ByteBuffer, Composite> computeNext() {
                        while (rowIter.hasNext()) {
                            Row<ByteBuffer, Composite> row = rowIter.next();
                            if (!row.getColumns().isEmpty()) {
                                return row;
                            }
                        }
                        return endOfData();
                    }
                };
            } finally {
                timer.stop();
            }
        }
    });
}
 
Example #25
Source File: AstyanaxStorageProvider.java    From emodb with Apache License 2.0 4 votes vote down vote up
private void purge(AstyanaxStorage storage, boolean deleteMetadata, boolean deleteData, Runnable progress) {
    BlobPlacement placement = (BlobPlacement) storage.getPlacement();
    CassandraKeyspace keyspace = placement.getKeyspace();
    ColumnFamily<ByteBuffer, Composite> cf = placement.getBlobColumnFamily();

    // Limit the query to a single column since we mainly just want the row keys (but not zero columns because
    // then we couldn't distinguish a live row from a row that has been deleted already).
    ByteBufferRange columnRange = new RangeBuilder().setLimit(1).build();

    MutationBatch mutation = keyspace.prepareMutationBatch(CONSISTENCY_STRONG);

    LimitCounter unlimited = LimitCounter.max();

    // Range query all the shards and delete all the rows we find.
    Iterator<ByteBufferRange> scanIter = storage.scanIterator(null);
    while (scanIter.hasNext()) {
        ByteBufferRange keyRange = scanIter.next();
        Iterator<Row<ByteBuffer, Composite>> rowIter = scanInternal(placement, keyRange, columnRange, unlimited);
        while (rowIter.hasNext()) {
            Row<ByteBuffer, Composite> row = rowIter.next();
            if (row.getColumns().isEmpty()) {
                continue;  // don't bother deleting range ghosts
            }

            if (deleteMetadata && deleteData) {
                mutation.withRow(cf, row.getKey()).delete();
            } else {
                if (deleteMetadata) {
                    mutation.withRow(cf, row.getKey())
                            .deleteColumn(getColumn(ColumnGroup.A, 0));
                }

                if (deleteData) {
                    mutation.withRow(cf, row.getKey())
                            .deleteColumn(getColumn(ColumnGroup.B, 1))
                            .deleteColumn(getColumn(ColumnGroup.Z, 2));
                }
            }

            if (mutation.getRowCount() >= 100) {
                progress.run();
                execute(mutation);
                mutation.discardMutations();
            }
        }
    }
    if (!mutation.isEmpty()) {
        progress.run();
        execute(mutation);
    }
}