Search in sources :

Example 66 with Value

use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.

the class StatsTrackingKeyValueService method get.

@Override
public Map<Cell, Value> get(TableReference tableRef, Map<Cell, Long> timestampByCell) {
    long start = System.currentTimeMillis();
    Map<Cell, Value> r = super.get(tableRef, timestampByCell);
    long finish = System.currentTimeMillis();
    // Update stats only after successful get.
    TableStats s = getTableStats(tableRef);
    long cellBytes = 0;
    for (Cell cell : timestampByCell.keySet()) {
        cellBytes += cell.getRowName().length;
        cellBytes += cell.getColumnName().length;
    }
    s.totalGetCellBytes.addAndGet(cellBytes);
    s.totalGetMillis.addAndGet(finish - start);
    s.totalGetCalls.incrementAndGet();
    updateGetStats(s, r);
    return r;
}
Also used : Value(com.palantir.atlasdb.keyvalue.api.Value) Cell(com.palantir.atlasdb.keyvalue.api.Cell)

Example 67 with Value

use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.

the class SweepStatsKeyValueService method flushWrites.

private void flushWrites(Multiset<TableReference> writes, Set<TableReference> clears) {
    if (writes.isEmpty() && clears.isEmpty()) {
        log.info("No writes to flush");
        return;
    }
    log.info("Flushing stats for {} writes and {} clears", SafeArg.of("writes", writes.size()), SafeArg.of("clears", clears.size()));
    log.trace("Flushing writes: {}", UnsafeArg.of("writes", writes));
    log.trace("Flushing clears: {}", UnsafeArg.of("clears", clears));
    try {
        Set<TableReference> tableNames = Sets.difference(writes.elementSet(), clears);
        Collection<byte[]> rows = Collections2.transform(Collections2.transform(tableNames, t -> t.getQualifiedName()), Functions.compose(Persistables.persistToBytesFunction(), SweepPriorityRow.fromFullTableNameFun()));
        Map<Cell, Value> oldWriteCounts = delegate().getRows(SWEEP_PRIORITY_TABLE, rows, SweepPriorityTable.getColumnSelection(SweepPriorityNamedColumn.WRITE_COUNT), Long.MAX_VALUE);
        Map<Cell, byte[]> newWriteCounts = Maps.newHashMapWithExpectedSize(writes.elementSet().size());
        byte[] col = SweepPriorityNamedColumn.WRITE_COUNT.getShortName();
        for (TableReference tableRef : tableNames) {
            Preconditions.checkState(!tableRef.getQualifiedName().startsWith(AtlasDbConstants.NAMESPACE_PREFIX), "The sweep stats kvs should wrap the namespace mapping kvs, not the other way around.");
            byte[] row = SweepPriorityRow.of(tableRef.getQualifiedName()).persistToBytes();
            Cell cell = Cell.create(row, col);
            Value oldValue = oldWriteCounts.get(cell);
            long oldCount = oldValue == null || oldValue.getContents().length == 0 ? 0 : SweepPriorityTable.WriteCount.BYTES_HYDRATOR.hydrateFromBytes(oldValue.getContents()).getValue();
            long newValue = clears.contains(tableRef) ? writes.count(tableRef) : oldCount + writes.count(tableRef);
            log.debug("Sweep priority for {} has {} writes (was {})", tableRef, newValue, oldCount);
            newWriteCounts.put(cell, SweepPriorityTable.WriteCount.of(newValue).persistValue());
        }
        long timestamp = timestampService.getFreshTimestamp();
        // Committing before writing is intentional, we want the start timestamp to
        // show up in the transaction table before we write do our writes.
        commit(timestamp);
        delegate().put(SWEEP_PRIORITY_TABLE, newWriteCounts, timestamp);
    } catch (RuntimeException e) {
        if (Thread.interrupted()) {
            return;
        }
        Set<TableReference> allTableNames = delegate().getAllTableNames();
        if (!allTableNames.contains(SWEEP_PRIORITY_TABLE) || !allTableNames.contains(TransactionConstants.TRANSACTION_TABLE)) {
            // ignore problems when sweep or transaction tables don't exist
            log.warn("Ignoring failed sweep stats flush due to ", e);
        }
        log.error("Unable to flush sweep stats for writes {} and clears {}: ", writes, clears, e);
        throw e;
    }
}
Also used : Multiset(com.google.common.collect.Multiset) LoggerFactory(org.slf4j.LoggerFactory) SweepSchema(com.palantir.atlasdb.schema.SweepSchema) SweepPriorityRow(com.palantir.atlasdb.schema.generated.SweepPriorityTable.SweepPriorityRow) Collections2(com.google.common.collect.Collections2) Multimap(com.google.common.collect.Multimap) Supplier(java.util.function.Supplier) Persistables(com.palantir.common.persist.Persistables) SweepPriorityNamedColumn(com.palantir.atlasdb.schema.generated.SweepPriorityTable.SweepPriorityNamedColumn) ClusterAvailabilityStatus(com.palantir.atlasdb.keyvalue.api.ClusterAvailabilityStatus) SafeArg(com.palantir.logsafe.SafeArg) PTExecutors(com.palantir.common.concurrent.PTExecutors) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ImmutableMultiset(com.google.common.collect.ImmutableMultiset) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) TimestampService(com.palantir.timestamp.TimestampService) AtlasDbConstants(com.palantir.atlasdb.AtlasDbConstants) Functions(com.google.common.base.Functions) Logger(org.slf4j.Logger) ImmutableSet(com.google.common.collect.ImmutableSet) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Value(com.palantir.atlasdb.keyvalue.api.Value) ImmutableMap(com.google.common.collect.ImmutableMap) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) RangeRequest(com.palantir.atlasdb.keyvalue.api.RangeRequest) SweepPriorityTable(com.palantir.atlasdb.schema.generated.SweepPriorityTable) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) TransactionConstants(com.palantir.atlasdb.transaction.impl.TransactionConstants) ConcurrentHashMultiset(com.google.common.collect.ConcurrentHashMultiset) UnsafeArg(com.palantir.logsafe.UnsafeArg) KeyValueService(com.palantir.atlasdb.keyvalue.api.KeyValueService) Entry(java.util.Map.Entry) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) Value(com.palantir.atlasdb.keyvalue.api.Value) Cell(com.palantir.atlasdb.keyvalue.api.Cell)

Example 68 with Value

use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.

the class ValidatingQueryRewritingKeyValueService method putWithTimestamps.

@Override
public void putWithTimestamps(TableReference tableRef, Multimap<Cell, Value> cellValues) throws KeyAlreadyExistsException {
    if (cellValues.isEmpty()) {
        return;
    }
    Validate.isTrue(!tableRef.equals(TransactionConstants.TRANSACTION_TABLE), TRANSACTION_ERROR);
    long lastTimestamp = -1;
    boolean allAtSameTimestamp = true;
    for (Value value : cellValues.values()) {
        long timestamp = value.getTimestamp();
        Validate.isTrue(timestamp != Long.MAX_VALUE);
        Validate.isTrue(timestamp >= 0);
        if (lastTimestamp != -1 && timestamp != lastTimestamp) {
            allAtSameTimestamp = false;
        }
        lastTimestamp = timestamp;
    }
    if (allAtSameTimestamp) {
        Multimap<Cell, byte[]> cellValuesWithStrippedTimestamp = Multimaps.transformValues(cellValues, Value.GET_VALUE);
        Map<Cell, byte[]> putMap = Maps.transformValues(cellValuesWithStrippedTimestamp.asMap(), input -> {
            try {
                return Iterables.getOnlyElement(input);
            } catch (IllegalArgumentException e) {
                log.error("Application tried to put multiple same-cell values in at same timestamp; attempting to perform last-write-wins, but ordering is not guaranteed.");
                return Iterables.getLast(input);
            }
        });
        put(tableRef, putMap, lastTimestamp);
        return;
    }
    delegate.putWithTimestamps(tableRef, cellValues);
}
Also used : Value(com.palantir.atlasdb.keyvalue.api.Value) Cell(com.palantir.atlasdb.keyvalue.api.Cell)

Example 69 with Value

use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.

the class CassandraKeyValueServiceTableCreationIntegrationTest method testCreateTableCanRestoreLostMetadata.

@Test
public void testCreateTableCanRestoreLostMetadata() {
    // setup a basic table
    TableReference missingMetadataTable = TableReference.createFromFullyQualifiedName("test.metadata_missing");
    byte[] initialMetadata = new TableDefinition() {

        {
            rowName();
            rowComponent("blob", ValueType.BLOB);
            columns();
            column("bar", "b", ValueType.BLOB);
            conflictHandler(ConflictHandler.IGNORE_ALL);
            sweepStrategy(TableMetadataPersistence.SweepStrategy.NOTHING);
        }
    }.toTableMetadata().persistToBytes();
    kvs.createTable(missingMetadataTable, initialMetadata);
    // retrieve the metadata and see that it's the same as what we just put in
    byte[] existingMetadata = kvs.getMetadataForTable(missingMetadataTable);
    assertThat(initialMetadata, is(existingMetadata));
    // Directly get and delete the metadata (`get` necessary to get the fake timestamp putMetadataForTables used)
    Cell cell = Cell.create(missingMetadataTable.getQualifiedName().getBytes(StandardCharsets.UTF_8), "m".getBytes(StandardCharsets.UTF_8));
    Value persistedMetadata = Iterables.getLast(kvs.get(AtlasDbConstants.DEFAULT_METADATA_TABLE, ImmutableMap.of(cell, Long.MAX_VALUE)).values());
    kvs.delete(AtlasDbConstants.DEFAULT_METADATA_TABLE, ImmutableMultimap.of(cell, persistedMetadata.getTimestamp()));
    // pretend we started up again and did a createTable() for our existing table, that no longer has metadata
    kvs.createTable(missingMetadataTable, initialMetadata);
    // retrieve the metadata again and see that it's the same as what we just put in
    existingMetadata = kvs.getMetadataForTable(missingMetadataTable);
    assertThat(initialMetadata, is(existingMetadata));
}
Also used : TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) Value(com.palantir.atlasdb.keyvalue.api.Value) TableDefinition(com.palantir.atlasdb.table.description.TableDefinition) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Test(org.junit.Test)

Example 70 with Value

use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.

the class CassandraKeyValueServiceImpl method get.

/**
 * Gets values from the key-value store.
 * <p>
 * Does not require all Cassandra nodes to be up and available, works as long as quorum is achieved.
 *
 * @param tableRef the name of the table to retrieve values from.
 * @param timestampByCell specifies, for each row, the maximum timestamp (exclusive) at which to
 *        retrieve that rows's value.
 *
 * @return map of retrieved values. Values which do not exist (either
 *         because they were deleted or never created in the first place)
 *         are simply not returned.
 *
 * @throws IllegalArgumentException if any of the requests were invalid
 *         (e.g., attempting to retrieve values from a non-existent table).
 */
@Override
public Map<Cell, Value> get(TableReference tableRef, Map<Cell, Long> timestampByCell) {
    if (timestampByCell.isEmpty()) {
        log.info("Attempted get on '{}' table with empty cells", LoggingArgs.tableRef(tableRef));
        return ImmutableMap.of();
    }
    try {
        Long firstTs = timestampByCell.values().iterator().next();
        if (Iterables.all(timestampByCell.values(), Predicates.equalTo(firstTs))) {
            return get("get", tableRef, timestampByCell.keySet(), firstTs);
        }
        SetMultimap<Long, Cell> cellsByTs = Multimaps.invertFrom(Multimaps.forMap(timestampByCell), HashMultimap.<Long, Cell>create());
        Builder<Cell, Value> builder = ImmutableMap.builder();
        for (long ts : cellsByTs.keySet()) {
            StartTsResultsCollector collector = new StartTsResultsCollector(ts);
            cellLoader.loadWithTs("get", tableRef, cellsByTs.get(ts), ts, false, collector, readConsistency);
            builder.putAll(collector.getCollectedResults());
        }
        return builder.build();
    } catch (Exception e) {
        throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
    }
}
Also used : StartTsResultsCollector(com.palantir.atlasdb.keyvalue.cassandra.CassandraKeyValueServices.StartTsResultsCollector) Value(com.palantir.atlasdb.keyvalue.api.Value) Cell(com.palantir.atlasdb.keyvalue.api.Cell) InsufficientConsistencyException(com.palantir.atlasdb.keyvalue.api.InsufficientConsistencyException) CheckAndSetException(com.palantir.atlasdb.keyvalue.api.CheckAndSetException) KeyAlreadyExistsException(com.palantir.atlasdb.keyvalue.api.KeyAlreadyExistsException) FunctionCheckedException(com.palantir.common.base.FunctionCheckedException) TException(org.apache.thrift.TException) UnavailableException(org.apache.cassandra.thrift.UnavailableException) PalantirRuntimeException(com.palantir.common.exception.PalantirRuntimeException)

Aggregations

Value (com.palantir.atlasdb.keyvalue.api.Value)74 Cell (com.palantir.atlasdb.keyvalue.api.Cell)55 RangeRequest (com.palantir.atlasdb.keyvalue.api.RangeRequest)20 RowResult (com.palantir.atlasdb.keyvalue.api.RowResult)18 Test (org.junit.Test)18 Entry (java.util.Map.Entry)16 TokenBackedBasicResultsPage (com.palantir.util.paging.TokenBackedBasicResultsPage)15 Map (java.util.Map)15 SortedMap (java.util.SortedMap)13 ImmutableMap (com.google.common.collect.ImmutableMap)12 TableReference (com.palantir.atlasdb.keyvalue.api.TableReference)10 LinkedHashMap (java.util.LinkedHashMap)9 ImmutableList (com.google.common.collect.ImmutableList)7 KeyAlreadyExistsException (com.palantir.atlasdb.keyvalue.api.KeyAlreadyExistsException)7 InsufficientConsistencyException (com.palantir.atlasdb.keyvalue.api.InsufficientConsistencyException)6 RowColumnRangeIterator (com.palantir.atlasdb.keyvalue.api.RowColumnRangeIterator)6 List (java.util.List)6 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)5 BatchColumnRangeSelection (com.palantir.atlasdb.keyvalue.api.BatchColumnRangeSelection)5 LocalRowColumnRangeIterator (com.palantir.atlasdb.keyvalue.impl.LocalRowColumnRangeIterator)5