use of com.cinchapi.concourse.thrift.TObject in project concourse by cinchapi.
the class Operations method maxKeyAtomic.
/**
* Use the {@code store} to atomically compute the max across all the values
* stored for {@code key} across all records at {@code timestamp}.
*
* @param key
* @param timestamp
* @param store
* @return the max
*/
public static Number maxKeyAtomic(String key, long timestamp, Store store) {
checkAtomicity(store, timestamp);
Map<TObject, Set<Long>> data = Stores.browse(store, key, timestamp);
TObject max = Iterables.getLast(data.keySet(), null);
if (max != null) {
return (Number) Convert.thriftToJava(max);
} else {
return null;
}
}
use of com.cinchapi.concourse.thrift.TObject in project concourse by cinchapi.
the class Operations method getKeyRecordsOptionalAtomic.
/**
* From {@code store}, get the most recently stored value at
* {@code timestamp} for {@code key} in each of the {@code records}.
*
* <p>
* If possible, apply the {@code order} and {@code page} parameters to the
* result set.
* </p>
*
* @param store
* @param key
* @param records
* @param timestamp
* @param order
* @param page
* @param supplier a {@link Supplier} of a {@link Sortable} in which the
* results can be gathered
* @return the result set - a {@link Map} from each of the relevant
* {@code records} to the most recently stored value for {@code key}
*/
public static <M extends Map<Long, TObject> & Sortable<TObject>> Map<Long, TObject> getKeyRecordsOptionalAtomic(Store store, String key, Iterable<Long> records, long timestamp, Order order, Page page, Supplier<M> supplier) {
M data = supplier.get();
if (order instanceof NoOrder) {
// If page == NoPage, this is a no-op; otherwise, apply the
// pagination directly to the input records so that we don't fetch
// more data than required.
records = Paging.page(records, page);
page = NoPage.INSTANCE;
}
for (long record : records) {
try {
Set<TObject> values = timestamp == Time.NONE ? Stores.select(store, key, record) : Stores.select(store, key, record, timestamp);
TObject value = Iterables.getLast(values);
data.put(record, value);
} catch (NoSuchElementException e) {
continue;
}
}
if (timestamp == Time.NONE) {
data.sort(Sorting.byValue(order, store));
} else {
data.sort(Sorting.byValue(order, store), timestamp);
}
// a no-op
return Paging.page(data, page);
}
use of com.cinchapi.concourse.thrift.TObject in project concourse by cinchapi.
the class Operations method revertAtomic.
/**
* Revert {@code key} in {@code record} to its state {@code timestamp} using
* the provided atomic {@code operation}.
*
* @param key
* @param record
* @param timestamp
* @param atomic
* @throws AtomicStateException
*/
public static void revertAtomic(String key, long record, long timestamp, AtomicOperation atomic) throws AtomicStateException {
Set<TObject> past = atomic.select(key, record, timestamp);
Set<TObject> present = atomic.select(key, record);
Set<TObject> xor = Sets.symmetricDifference(past, present);
for (TObject value : xor) {
if (present.contains(value)) {
atomic.remove(key, value, record);
} else {
atomic.add(key, value, record);
}
}
}
use of com.cinchapi.concourse.thrift.TObject in project concourse by cinchapi.
the class Stores method lookupWithStrategy.
/**
* Use the {@link Strategy} framework to lookup {@code key} in
* {@code record} at {@code timestamp} within {@code store}.
* <p>
* It is assumed that the {@code key} is a {@link KeyType#WRITABLE_KEY
* writable key}.
* </p>
*
* @param store
* @param key
* @param record
* @param timestamp
* @return the set of {@link TObject values} stored in {@code store} for
* {@code key} in {@code record}.
*/
private static Set<TObject> lookupWithStrategy(Store store, String key, long record, long timestamp) {
Source source;
if (Command.isSet()) {
Strategy strategy = new Strategy(Command.current(), store);
source = strategy.source(key, record);
} else {
source = Source.FIELD;
}
Set<TObject> values;
if (source == Source.RECORD) {
// @formatter:off
Map<String, Set<TObject>> stored = timestamp == Time.NONE ? store.select(record) : store.select(record, timestamp);
values = MoreObjects.firstNonNull(stored.get(key), ImmutableSet.of());
// @formatter:on
} else if (source == Source.FIELD) {
// @formatter:off
values = timestamp == Time.NONE ? store.select(key, record) : store.select(key, record, timestamp);
// @formatter:on
} else {
// source == Source.INDEX
// @formatter:off
values = timestamp == Time.NONE ? store.gather(key, record) : store.gather(key, record, timestamp);
// @formatter:on
}
return values;
}
use of com.cinchapi.concourse.thrift.TObject in project concourse by cinchapi.
the class Stores method serialSelect.
/**
* Select the values stored for {@code key} in {@code record} at
* {@code timestamp} from the {@code store}.
* <p>
* If the {@code key} is primitive, the store retrieval is usually a simple
* {@link Store#select(long) select}. However, if the key is a navigation
* key, this method will process it via
* {@link Operations#traverseKeyRecordOptionalAtomic(String, long, long, AtomicOperation)}
* if the {@code store} is an {@link AtomicOperation} or
* {@link AtomicSupport supports} starting one.
* </p>
*
* @param store
* @param key
* @param record
* @param timestamp
*
* @return the values stored for {@code key} in {@code record} at
* {@code timestamp} according to the {@code store}
*/
protected static Set<TObject> serialSelect(Store store, String key, long record, long timestamp) {
Function evalFunc;
if (Keys.isNavigationKey(key)) {
if (store instanceof AtomicOperation || timestamp != Time.NONE) {
return Operations.traverseKeyRecordOptionalAtomic(key, record, timestamp, store);
} else if (store instanceof AtomicSupport) {
AtomicReference<Set<TObject>> value = new AtomicReference<>(ImmutableSet.of());
AtomicOperations.executeWithRetry((AtomicSupport) store, (atomic) -> {
value.set(Operations.traverseKeyRecordOptionalAtomic(key, record, timestamp, atomic));
});
return value.get();
} else {
throw new UnsupportedOperationException("Cannot fetch the current values of a navigation key using a Store that does not support atomic operations");
}
} else if ((evalFunc = Keys.tryParseFunction(key)) != null) {
String method = Calculations.alias(evalFunc.operation()) + "KeyRecordAtomic";
Number value = Reflection.callStatic(Operations.class, method, evalFunc.key(), record, timestamp, store);
return value != null ? ImmutableSet.of(Convert.javaToThrift(value)) : ImmutableSet.of();
} else if (key.equals(Constants.JSON_RESERVED_IDENTIFIER_NAME)) {
return ImmutableSet.of(Convert.javaToThrift(record));
} else {
Source source;
if (Command.isSet()) {
Strategy strategy = new Strategy(Command.current(), store);
source = strategy.source(key, record);
} else {
source = Source.FIELD;
}
Set<TObject> values;
if (source == Source.RECORD) {
// @formatter:off
Map<String, Set<TObject>> data = timestamp == Time.NONE ? store.select(record) : store.select(record, timestamp);
values = data.getOrDefault(key, ImmutableSet.of());
// @formatter:on
} else if (source == Source.FIELD) {
// @formatter:off
values = timestamp == Time.NONE ? store.select(key, record) : store.select(key, record, timestamp);
// @formatter:on
} else {
// source == Source.INDEX
// @formatter:off
values = timestamp == Time.NONE ? store.gather(key, record) : store.gather(key, record, timestamp);
// @formatter:on
}
return values;
}
}
Aggregations