use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class StandardLockCleanerRunnable method runWithExceptions.
private void runWithExceptions() throws BackendException {
StaticBuffer lockKey = serializer.toLockKey(target.getKey(), target.getColumn());
// TODO reduce LOCK_COL_END based on cutoff
List<Entry> locks = store.getSlice(new KeySliceQuery(lockKey, LOCK_COL_START, LOCK_COL_END), tx);
ImmutableList.Builder<StaticBuffer> b = ImmutableList.builder();
for (Entry lc : locks) {
TimestampRid tr = serializer.fromLockColumn(lc.getColumn(), times);
if (tr.getTimestamp().isBefore(cutoff)) {
log.info("Deleting expired lock on {} by rid {} with timestamp {} (before or at cutoff {})", target, tr.getRid(), tr.getTimestamp(), cutoff);
b.add(lc.getColumn());
} else {
log.debug("Ignoring lock on {} by rid {} with timestamp {} (timestamp is after cutoff {})", target, tr.getRid(), tr.getTimestamp(), cutoff);
}
}
List<StaticBuffer> deletions = b.build();
if (!deletions.isEmpty()) {
store.mutate(lockKey, ImmutableList.of(), deletions, tx);
log.info("Deleted {} expired locks (before or at cutoff {})", deletions.size(), cutoff);
}
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class AstyanaxStoreManager method mutateMany.
@Override
public void mutateMany(Map<String, Map<StaticBuffer, KCVMutation>> batch, StoreTransaction txh) throws BackendException {
MutationBatch m = keyspaceContext.getClient().prepareMutationBatch().withAtomicBatch(atomicBatch).setConsistencyLevel(getTx(txh).getWriteConsistencyLevel().getAstyanax()).withRetryPolicy(retryPolicy.duplicate());
final MaskedTimestamp commitTime = new MaskedTimestamp(txh);
for (Map.Entry<String, Map<StaticBuffer, KCVMutation>> batchentry : batch.entrySet()) {
String storeName = batchentry.getKey();
Preconditions.checkArgument(openStores.containsKey(storeName), "Store cannot be found: " + storeName);
ColumnFamily<ByteBuffer, ByteBuffer> columnFamily = openStores.get(storeName).getColumnFamily();
Map<StaticBuffer, KCVMutation> mutations = batchentry.getValue();
for (Map.Entry<StaticBuffer, KCVMutation> ent : mutations.entrySet()) {
// The CLMs for additions and deletions are separated because
// Astyanax's operation timestamp cannot be set on a per-delete
// or per-addition basis.
KCVMutation janusgraphMutation = ent.getValue();
ByteBuffer key = ent.getKey().asByteBuffer();
if (janusgraphMutation.hasDeletions()) {
ColumnListMutation<ByteBuffer> deletions = m.withRow(columnFamily, key);
deletions.setTimestamp(commitTime.getDeletionTime(times));
for (StaticBuffer b : janusgraphMutation.getDeletions()) deletions.deleteColumn(b.as(StaticBuffer.BB_FACTORY));
}
if (janusgraphMutation.hasAdditions()) {
ColumnListMutation<ByteBuffer> updates = m.withRow(columnFamily, key);
updates.setTimestamp(commitTime.getAdditionTime(times));
for (Entry e : janusgraphMutation.getAdditions()) {
Integer ttl = (Integer) e.getMetaData().get(EntryMetaData.TTL);
if (null != ttl && ttl > 0) {
updates.putColumn(e.getColumnAs(StaticBuffer.BB_FACTORY), e.getValueAs(StaticBuffer.BB_FACTORY), ttl);
} else {
updates.putColumn(e.getColumnAs(StaticBuffer.BB_FACTORY), e.getValueAs(StaticBuffer.BB_FACTORY));
}
}
}
}
}
try {
m.execute();
} catch (ConnectionException e) {
throw new TemporaryBackendException(e);
}
sleepAfterWrite(txh, commitTime);
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class ModificationDeserializer method parseRelation.
public static InternalRelation parseRelation(TransactionLogHeader.Modification modification, StandardJanusGraphTx tx) {
Change state = modification.state;
assert state.isProper();
long outVertexId = modification.outVertexId;
Entry relEntry = modification.relationEntry;
InternalVertex outVertex = tx.getInternalVertex(outVertexId);
// Special relation parsing, compare to {@link RelationConstructor}
RelationCache relCache = tx.getEdgeSerializer().readRelation(relEntry, false, tx);
assert relCache.direction == Direction.OUT;
InternalRelationType type = (InternalRelationType) tx.getExistingRelationType(relCache.typeId);
assert type.getBaseType() == null;
InternalRelation rel;
if (type.isPropertyKey()) {
if (state == Change.REMOVED) {
rel = new StandardVertexProperty(relCache.relationId, (PropertyKey) type, outVertex, relCache.getValue(), ElementLifeCycle.Removed);
} else {
rel = new CacheVertexProperty(relCache.relationId, (PropertyKey) type, outVertex, relCache.getValue(), relEntry);
}
} else {
assert type.isEdgeLabel();
InternalVertex otherVertex = tx.getInternalVertex(relCache.getOtherVertexId());
if (state == Change.REMOVED) {
rel = new StandardEdge(relCache.relationId, (EdgeLabel) type, outVertex, otherVertex, ElementLifeCycle.Removed);
} else {
rel = new CacheEdge(relCache.relationId, (EdgeLabel) type, outVertex, otherVertex, relEntry);
}
}
if (state == Change.REMOVED && relCache.hasProperties()) {
// copy over properties
for (LongObjectCursor<Object> entry : relCache) {
rel.setPropertyDirect(tx.getExistingPropertyKey(entry.key), entry.value);
}
}
return rel;
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class IndexRemoveJob method process.
@Override
public void process(StaticBuffer key, Map<SliceQuery, EntryList> entries, ScanMetrics metrics) {
// The queries are already tailored enough => everything should be removed
try {
BackendTransaction mutator = writeTx.getTxHandle();
final List<Entry> deletions;
if (entries.size() == 1)
deletions = Iterables.getOnlyElement(entries.values());
else {
final int size = IteratorUtils.stream(entries.values().iterator()).map(List::size).reduce(0, (x, y) -> x + y);
deletions = new ArrayList<>(size);
entries.values().forEach(deletions::addAll);
}
metrics.incrementCustom(DELETED_RECORDS_COUNT, deletions.size());
if (isRelationTypeIndex()) {
mutator.mutateEdges(key, KCVSCache.NO_ADDITIONS, deletions);
} else {
mutator.mutateIndex(key, KCVSCache.NO_ADDITIONS, deletions);
}
} catch (final Exception e) {
managementSystem.rollback();
writeTx.rollback();
metrics.incrementCustom(FAILED_TX);
throw new JanusGraphException(e.getMessage(), e);
}
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class ColumnValueStore method mutate.
synchronized void mutate(List<Entry> additions, List<StaticBuffer> deletions, StoreTransaction txh) {
// Prepare data
Entry[] add;
if (!additions.isEmpty()) {
add = new Entry[additions.size()];
int pos = 0;
for (Entry e : additions) {
add[pos] = e;
pos++;
}
Arrays.sort(add);
} else
add = new Entry[0];
// Filter out deletions that are also added
Entry[] del;
if (!deletions.isEmpty()) {
del = new Entry[deletions.size()];
int pos = 0;
for (StaticBuffer deletion : deletions) {
Entry delEntry = StaticArrayEntry.of(deletion);
if (Arrays.binarySearch(add, delEntry) >= 0)
continue;
del[pos++] = delEntry;
}
if (pos < deletions.size())
del = Arrays.copyOf(del, pos);
Arrays.sort(del);
} else
del = new Entry[0];
Lock lock = getLock(txh);
lock.lock();
try {
Entry[] oldData = data.array;
int oldSize = data.size;
Entry[] newData = new Entry[oldSize + add.length];
// Merge sort
int i = 0, indexOld = 0, indexAdd = 0, indexDelete = 0;
while (indexOld < oldSize) {
Entry e = oldData[indexOld];
indexOld++;
// Compare with additions
if (indexAdd < add.length) {
int compare = e.compareTo(add[indexAdd]);
if (compare >= 0) {
e = add[indexAdd];
indexAdd++;
// Skip duplicates
while (indexAdd < add.length && e.equals(add[indexAdd])) indexAdd++;
}
if (compare > 0)
indexOld--;
}
// Compare with deletions
if (indexDelete < del.length) {
int compare = e.compareTo(del[indexDelete]);
if (compare == 0)
e = null;
if (compare >= 0)
indexDelete++;
}
if (e != null) {
newData[i] = e;
i++;
}
}
while (indexAdd < add.length) {
newData[i] = add[indexAdd];
i++;
indexAdd++;
}
if (i * 1.0 / newData.length < SIZE_THRESHOLD) {
// shrink array to free space
Entry[] tempData = newData;
newData = new Entry[i];
System.arraycopy(tempData, 0, newData, 0, i);
}
data = new Data(newData, i);
} finally {
lock.unlock();
}
}
Aggregations