use of org.janusgraph.graphdb.database.EdgeSerializer in project janusgraph by JanusGraph.
the class BasicVertexCentricQueryBuilder method constructSliceQueries.
private void constructSliceQueries(PropertyKey[] extendedSortKey, EdgeSerializer.TypedInterval[] sortKeyConstraints, int position, InternalRelationType bestCandidate, Direction direction, Map<RelationType, Interval> intervalConstraints, int sliceLimit, boolean isIntervalFittedConditions, boolean bestCandidateSupportsOrder, List<BackendQueryHolder<SliceQuery>> queries) {
if (position < extendedSortKey.length) {
PropertyKey keyType = extendedSortKey[position];
Interval interval = intervalConstraints.get(keyType);
if (interval != null) {
sortKeyConstraints[position] = new EdgeSerializer.TypedInterval(keyType, interval);
position++;
}
if (interval != null && interval.isPoints()) {
// Keep invoking recursively to see if we can satisfy more constraints...
for (Object point : interval.getPoints()) {
EdgeSerializer.TypedInterval[] clonedSKC = Arrays.copyOf(sortKeyConstraints, sortKeyConstraints.length);
clonedSKC[position - 1] = new EdgeSerializer.TypedInterval(keyType, new PointInterval(point));
constructSliceQueries(extendedSortKey, clonedSKC, position, bestCandidate, direction, intervalConstraints, sliceLimit, isIntervalFittedConditions, bestCandidateSupportsOrder, queries);
}
return;
}
}
// ...otherwise this is it and we can construct the slicequery
boolean isFitted = isIntervalFittedConditions && position == intervalConstraints.size();
if (isFitted && position > 0) {
// If the last interval is open ended toward the larger values, then its not fitted because we need to
// filter out NULL values which are serialized with -1 (largest value) byte up front.
EdgeSerializer.TypedInterval lastInterval = sortKeyConstraints[position - 1];
if (!lastInterval.interval.isPoints() && lastInterval.interval.getEnd() == null)
isFitted = false;
}
EdgeSerializer serializer = tx.getEdgeSerializer();
SliceQuery q = serializer.getQuery(bestCandidate, direction, sortKeyConstraints);
q.setLimit(computeLimit(intervalConstraints.size() - position, sliceLimit));
queries.add(new BackendQueryHolder<>(q, isFitted, bestCandidateSupportsOrder));
}
use of org.janusgraph.graphdb.database.EdgeSerializer in project janusgraph by JanusGraph.
the class IndexRepairJob method process.
@Override
public void process(JanusGraphVertex vertex, ScanMetrics metrics) {
try {
BackendTransaction mutator = writeTx.getTxHandle();
if (index instanceof RelationTypeIndex) {
RelationTypeIndexWrapper wrapper = (RelationTypeIndexWrapper) index;
InternalRelationType wrappedType = wrapper.getWrappedType();
EdgeSerializer edgeSerializer = writeTx.getEdgeSerializer();
List<Entry> additions = new ArrayList<>();
for (Object relation : vertex.query().types(indexRelationTypeName).direction(Direction.OUT).relations()) {
InternalRelation janusgraphRelation = (InternalRelation) relation;
for (int pos = 0; pos < janusgraphRelation.getArity(); pos++) {
if (!wrappedType.isUnidirected(Direction.BOTH) && !wrappedType.isUnidirected(EdgeDirection.fromPosition(pos)))
// Directionality is not covered
continue;
Entry entry = edgeSerializer.writeRelation(janusgraphRelation, wrappedType, pos, writeTx);
additions.add(entry);
}
}
StaticBuffer vertexKey = writeTx.getIdInspector().getKey(vertex.longId());
mutator.mutateEdges(vertexKey, additions, KCVSCache.NO_DELETIONS);
metrics.incrementCustom(ADDED_RECORDS_COUNT, additions.size());
} else if (index instanceof JanusGraphIndex) {
IndexType indexType = managementSystem.getSchemaVertex(index).asIndexType();
assert indexType != null;
IndexSerializer indexSerializer = graph.getIndexSerializer();
// Gather elements to index
List<JanusGraphElement> elements;
switch(indexType.getElement()) {
case VERTEX:
elements = ImmutableList.of(vertex);
break;
case PROPERTY:
elements = Lists.newArrayList();
for (JanusGraphVertexProperty p : addIndexSchemaConstraint(vertex.query(), indexType).properties()) {
elements.add(p);
}
break;
case EDGE:
elements = Lists.newArrayList();
for (Object e : addIndexSchemaConstraint(vertex.query().direction(Direction.OUT), indexType).edges()) {
elements.add((JanusGraphEdge) e);
}
break;
default:
throw new AssertionError("Unexpected category: " + indexType.getElement());
}
if (indexType.isCompositeIndex()) {
for (JanusGraphElement element : elements) {
Set<IndexSerializer.IndexUpdate<StaticBuffer, Entry>> updates = indexSerializer.reindexElement(element, (CompositeIndexType) indexType);
for (IndexSerializer.IndexUpdate<StaticBuffer, Entry> update : updates) {
log.debug("Mutating index {}: {}", indexType, update.getEntry());
mutator.mutateIndex(update.getKey(), Lists.newArrayList(update.getEntry()), KCVSCache.NO_DELETIONS);
metrics.incrementCustom(ADDED_RECORDS_COUNT);
}
}
} else {
assert indexType.isMixedIndex();
Map<String, Map<String, List<IndexEntry>>> documentsPerStore = new HashMap<>();
for (JanusGraphElement element : elements) {
indexSerializer.reindexElement(element, (MixedIndexType) indexType, documentsPerStore);
metrics.incrementCustom(DOCUMENT_UPDATES_COUNT);
}
mutator.getIndexTransaction(indexType.getBackingIndexName()).restore(documentsPerStore);
}
} else
throw new UnsupportedOperationException("Unsupported index found: " + index);
} catch (final Exception e) {
managementSystem.rollback();
writeTx.rollback();
metrics.incrementCustom(FAILED_TX);
throw new JanusGraphException(e.getMessage(), e);
}
}
use of org.janusgraph.graphdb.database.EdgeSerializer in project janusgraph by JanusGraph.
the class BasicVertexCentricQueryBuilder method constructQueryWithoutProfile.
protected BaseVertexCentricQuery constructQueryWithoutProfile(RelationCategory returnType) {
assert returnType != null;
Preconditions.checkArgument(adjacentVertex == null || returnType == RelationCategory.EDGE, "Vertex constraints only apply to edges");
if (limit <= 0)
return BaseVertexCentricQuery.emptyQuery();
// Prepare direction
if (returnType == RelationCategory.PROPERTY) {
if (dir == Direction.IN)
return BaseVertexCentricQuery.emptyQuery();
dir = Direction.OUT;
}
// Prepare order
orders.makeImmutable();
assert orders.hasCommonOrder();
// Prepare constraints
And<JanusGraphRelation> conditions = QueryUtil.constraints2QNF(tx, constraints);
if (conditions == null)
return BaseVertexCentricQuery.emptyQuery();
// Don't be smart with query limit adjustments - it just messes up the caching layer and
// penalizes when appropriate limits are set by the user!
int sliceLimit = limit;
// Construct (optimal) SliceQueries
EdgeSerializer serializer = tx.getEdgeSerializer();
List<BackendQueryHolder<SliceQuery>> queries;
if (!hasTypes()) {
final BackendQueryHolder<SliceQuery> query = new BackendQueryHolder<>(serializer.getQuery(returnType, querySystem), ((dir == Direction.BOTH || (returnType == RelationCategory.PROPERTY && dir == Direction.OUT)) && !conditions.hasChildren()), orders.isEmpty());
if (sliceLimit != Query.NO_LIMIT && sliceLimit < Integer.MAX_VALUE / 3) {
// half will be filtered
if (dir != Direction.BOTH && (returnType == RelationCategory.EDGE || returnType == RelationCategory.RELATION)) {
sliceLimit *= 2;
}
}
query.getBackendQuery().setLimit(computeLimit(conditions.size(), sliceLimit));
queries = ImmutableList.of(query);
conditions.add(returnType);
conditions.add(new VisibilityFilterCondition<>(// Need this to filter out newly created invisible relations in the transaction
querySystem ? VisibilityFilterCondition.Visibility.SYSTEM : VisibilityFilterCondition.Visibility.NORMAL));
} else {
final Set<RelationType> ts = new HashSet<>(types.length);
queries = new ArrayList<>(types.length + 2);
final Map<RelationType, Interval> intervalConstraints = new HashMap<>(conditions.size());
final boolean isIntervalFittedConditions = compileConstraints(conditions, intervalConstraints);
for (Interval pint : intervalConstraints.values()) {
// Check if one of the constraints leads to an empty result set
if (pint.isEmpty())
return BaseVertexCentricQuery.emptyQuery();
}
for (String typeName : types) {
InternalRelationType type = QueryUtil.getType(tx, typeName);
if (type == null)
continue;
Preconditions.checkArgument(!querySystem || (type instanceof SystemRelationType), "Can only query for system types: %s", type);
if (type instanceof ImplicitKey) {
throw new UnsupportedOperationException("Implicit types are not supported in complex queries: " + type);
}
ts.add(type);
Direction typeDir = dir;
if (type.isPropertyKey()) {
Preconditions.checkArgument(returnType != RelationCategory.EDGE, "Querying for edges but including a property key: " + type.name());
returnType = RelationCategory.PROPERTY;
typeDir = Direction.OUT;
}
if (type.isEdgeLabel()) {
Preconditions.checkArgument(returnType != RelationCategory.PROPERTY, "Querying for properties but including an edge label: " + type.name());
returnType = RelationCategory.EDGE;
if (!type.isUnidirected(Direction.BOTH)) {
// Make sure unidirectionality lines up
if (typeDir == Direction.BOTH) {
if (type.isUnidirected(Direction.OUT))
typeDir = Direction.OUT;
else
typeDir = Direction.IN;
} else // Directions are incompatible
if (!type.isUnidirected(typeDir))
continue;
}
}
if (type.isEdgeLabel() && typeDir == Direction.BOTH && intervalConstraints.isEmpty() && orders.isEmpty()) {
// TODO: This if-condition is a little too restrictive - we also want to include those cases where
// there ARE intervalConstraints or orders but those cannot be covered by any sort-keys
SliceQuery q = serializer.getQuery(type, typeDir, null);
q.setLimit(sliceLimit);
queries.add(new BackendQueryHolder<>(q, isIntervalFittedConditions, true));
} else {
// Optimize for each direction independently
Direction[] dirs = { typeDir };
if (typeDir == Direction.BOTH) {
if (type.isEdgeLabel())
dirs = new Direction[] { Direction.OUT, Direction.IN };
else
// property key
dirs = new Direction[] { Direction.OUT };
}
for (Direction direction : dirs) {
/*
Find best scoring relation type to answer this query with. We score each candidate by the number
of conditions that each sort-keys satisfy. Equality conditions score higher than interval
conditions since they are more restrictive. We assign additional points if the sort key
satisfies the order of this query.
*/
InternalRelationType bestCandidate = null;
double bestScore = Double.NEGATIVE_INFINITY;
boolean bestCandidateSupportsOrder = false;
for (InternalRelationType candidate : type.getRelationIndexes()) {
// Filter out those that don't apply
if (!candidate.isUnidirected(Direction.BOTH) && !candidate.isUnidirected(direction)) {
continue;
}
if (!candidate.equals(type) && candidate.getStatus() != SchemaStatus.ENABLED)
continue;
boolean supportsOrder = orders.isEmpty() || orders.getCommonOrder() == candidate.getSortOrder();
int currentOrder = 0;
double score = 0.0;
PropertyKey[] extendedSortKey = getExtendedSortKey(candidate, direction, tx);
for (PropertyKey keyType : extendedSortKey) {
if (currentOrder < orders.size() && orders.getKey(currentOrder).equals(keyType))
currentOrder++;
Interval interval = intervalConstraints.get(keyType);
if (interval == null || !interval.isPoints()) {
if (interval != null)
score += 1;
break;
} else {
assert interval.isPoints();
score += 5.0 / interval.getPoints().size();
}
}
if (supportsOrder && currentOrder == orders.size())
score += 3;
if (score > bestScore) {
bestScore = score;
bestCandidate = candidate;
bestCandidateSupportsOrder = supportsOrder && currentOrder == orders.size();
}
}
Preconditions.checkArgument(bestCandidate != null, "Current graph schema does not support the specified query constraints for type: %s", type.name());
// Construct sort key constraints for the best candidate and then serialize into a SliceQuery
// that is wrapped into a BackendQueryHolder
PropertyKey[] extendedSortKey = getExtendedSortKey(bestCandidate, direction, tx);
EdgeSerializer.TypedInterval[] sortKeyConstraints = new EdgeSerializer.TypedInterval[extendedSortKey.length];
constructSliceQueries(extendedSortKey, sortKeyConstraints, 0, bestCandidate, direction, intervalConstraints, sliceLimit, isIntervalFittedConditions, bestCandidateSupportsOrder, queries);
}
}
}
if (queries.isEmpty())
return BaseVertexCentricQuery.emptyQuery();
conditions.add(getTypeCondition(ts));
}
return new BaseVertexCentricQuery(QueryUtil.simplifyQNF(conditions), dir, queries, orders, limit);
}
use of org.janusgraph.graphdb.database.EdgeSerializer in project janusgraph by JanusGraph.
the class JanusGraphTest method simpleLogTest.
public void simpleLogTest(final boolean withLogFailure) throws InterruptedException {
final String userLogName = "test";
final Serializer serializer = graph.getDataSerializer();
final EdgeSerializer edgeSerializer = graph.getEdgeSerializer();
final TimestampProvider times = graph.getConfiguration().getTimestampProvider();
final Instant startTime = times.getTime();
clopen(option(SYSTEM_LOG_TRANSACTIONS), true, option(LOG_BACKEND, USER_LOG), (withLogFailure ? TestMockLog.class.getName() : LOG_BACKEND.getDefaultValue()), option(TestMockLog.LOG_MOCK_FAILADD, USER_LOG), withLogFailure, option(KCVSLog.LOG_READ_LAG_TIME, USER_LOG), Duration.ofMillis(50), option(LOG_READ_INTERVAL, USER_LOG), Duration.ofMillis(250), option(LOG_SEND_DELAY, USER_LOG), Duration.ofMillis(100), option(KCVSLog.LOG_READ_LAG_TIME, TRANSACTION_LOG), Duration.ofMillis(50), option(LOG_READ_INTERVAL, TRANSACTION_LOG), Duration.ofMillis(250), option(MAX_COMMIT_TIME), Duration.ofSeconds(1));
final String instanceId = graph.getConfiguration().getUniqueGraphId();
PropertyKey weight = tx.makePropertyKey("weight").dataType(Float.class).cardinality(Cardinality.SINGLE).make();
EdgeLabel knows = tx.makeEdgeLabel("knows").make();
JanusGraphVertex n1 = tx.addVertex("weight", 10.5);
newTx();
final Instant[] txTimes = new Instant[4];
// Transaction with custom user log name
txTimes[0] = times.getTime();
JanusGraphTransaction tx2 = graph.buildTransaction().logIdentifier(userLogName).start();
JanusGraphVertex v1 = tx2.addVertex("weight", 111.1);
v1.addEdge("knows", v1);
tx2.commit();
final long v1id = getId(v1);
txTimes[1] = times.getTime();
tx2 = graph.buildTransaction().logIdentifier(userLogName).start();
JanusGraphVertex v2 = tx2.addVertex("weight", 222.2);
v2.addEdge("knows", getV(tx2, v1id));
tx2.commit();
final long v2id = getId(v2);
// Only read tx
tx2 = graph.buildTransaction().logIdentifier(userLogName).start();
v1 = getV(tx2, v1id);
assertEquals(111.1, v1.<Float>value("weight").doubleValue(), 0.01);
assertEquals(222.2, getV(tx2, v2).<Float>value("weight").doubleValue(), 0.01);
tx2.commit();
// Deleting transaction
txTimes[2] = times.getTime();
tx2 = graph.buildTransaction().logIdentifier(userLogName).start();
v2 = getV(tx2, v2id);
assertEquals(222.2, v2.<Float>value("weight").doubleValue(), 0.01);
v2.remove();
tx2.commit();
// Edge modifying transaction
txTimes[3] = times.getTime();
tx2 = graph.buildTransaction().logIdentifier(userLogName).start();
v1 = getV(tx2, v1id);
assertEquals(111.1, v1.<Float>value("weight").doubleValue(), 0.01);
final Edge e = Iterables.getOnlyElement(v1.query().direction(Direction.OUT).labels("knows").edges());
assertFalse(e.property("weight").isPresent());
e.property("weight", 44.4);
tx2.commit();
close();
final Instant endTime = times.getTime();
final ReadMarker startMarker = ReadMarker.fromTime(startTime);
final Log transactionLog = openTxLog();
final Log userLog = openUserLog(userLogName);
final EnumMap<LogTxStatus, AtomicInteger> txMsgCounter = new EnumMap<>(LogTxStatus.class);
for (final LogTxStatus status : LogTxStatus.values()) txMsgCounter.put(status, new AtomicInteger(0));
final AtomicInteger userLogMeta = new AtomicInteger(0);
transactionLog.registerReader(startMarker, new MessageReader() {
@Override
public void read(Message message) {
final Instant msgTime = message.getTimestamp();
assertTrue(msgTime.isAfter(startTime) || msgTime.equals(startTime));
assertNotNull(message.getSenderId());
final TransactionLogHeader.Entry txEntry = TransactionLogHeader.parse(message.getContent(), serializer, times);
final TransactionLogHeader header = txEntry.getHeader();
// System.out.println(header.getTimestamp(TimeUnit.MILLISECONDS));
assertTrue(header.getTimestamp().isAfter(startTime) || header.getTimestamp().equals(startTime));
assertTrue(header.getTimestamp().isBefore(msgTime) || header.getTimestamp().equals(msgTime));
assertNotNull(txEntry.getMetadata());
assertNull(txEntry.getMetadata().get(LogTxMeta.GROUPNAME));
final LogTxStatus status = txEntry.getStatus();
if (status == LogTxStatus.PRECOMMIT) {
assertTrue(txEntry.hasContent());
final Object logId = txEntry.getMetadata().get(LogTxMeta.LOG_ID);
if (logId != null) {
assertTrue(logId instanceof String);
assertEquals(userLogName, logId);
userLogMeta.incrementAndGet();
}
} else if (withLogFailure) {
assertTrue(status.isPrimarySuccess() || status == LogTxStatus.SECONDARY_FAILURE);
if (status == LogTxStatus.SECONDARY_FAILURE) {
final TransactionLogHeader.SecondaryFailures secFail = txEntry.getContentAsSecondaryFailures(serializer);
assertTrue(secFail.failedIndexes.isEmpty());
assertTrue(secFail.userLogFailure);
}
} else {
assertFalse(txEntry.hasContent());
assertTrue(status.isSuccess());
}
txMsgCounter.get(txEntry.getStatus()).incrementAndGet();
}
@Override
public void updateState() {
}
});
final EnumMap<Change, AtomicInteger> userChangeCounter = new EnumMap<>(Change.class);
for (final Change change : Change.values()) userChangeCounter.put(change, new AtomicInteger(0));
final AtomicInteger userLogMsgCounter = new AtomicInteger(0);
userLog.registerReader(startMarker, new MessageReader() {
@Override
public void read(Message message) {
final Instant msgTime = message.getTimestamp();
assertTrue(msgTime.isAfter(startTime) || msgTime.equals(startTime));
assertNotNull(message.getSenderId());
final StaticBuffer content = message.getContent();
assertTrue(content != null && content.length() > 0);
final TransactionLogHeader.Entry transactionEntry = TransactionLogHeader.parse(content, serializer, times);
final Instant txTime = transactionEntry.getHeader().getTimestamp();
assertTrue(txTime.isBefore(msgTime) || txTime.equals(msgTime));
assertTrue(txTime.isAfter(startTime) || txTime.equals(msgTime));
final long transactionId = transactionEntry.getHeader().getId();
assertTrue(transactionId > 0);
transactionEntry.getContentAsModifications(serializer).forEach(modification -> {
assertTrue(modification.state == Change.ADDED || modification.state == Change.REMOVED);
userChangeCounter.get(modification.state).incrementAndGet();
});
userLogMsgCounter.incrementAndGet();
}
@Override
public void updateState() {
}
});
Thread.sleep(4000);
assertEquals(5, txMsgCounter.get(LogTxStatus.PRECOMMIT).get());
assertEquals(4, txMsgCounter.get(LogTxStatus.PRIMARY_SUCCESS).get());
assertEquals(1, txMsgCounter.get(LogTxStatus.COMPLETE_SUCCESS).get());
assertEquals(4, userLogMeta.get());
if (withLogFailure)
assertEquals(4, txMsgCounter.get(LogTxStatus.SECONDARY_FAILURE).get());
else
assertEquals(4, txMsgCounter.get(LogTxStatus.SECONDARY_SUCCESS).get());
// User-Log
if (withLogFailure) {
assertEquals(0, userLogMsgCounter.get());
} else {
assertEquals(4, userLogMsgCounter.get());
assertEquals(7, userChangeCounter.get(Change.ADDED).get());
assertEquals(4, userChangeCounter.get(Change.REMOVED).get());
}
clopen(option(VERBOSE_TX_RECOVERY), true);
/*
Transaction Recovery
*/
final TransactionRecovery recovery = JanusGraphFactory.startTransactionRecovery(graph, startTime);
/*
Use user log processing framework
*/
final AtomicInteger userLogCount = new AtomicInteger(0);
final LogProcessorFramework userLogs = JanusGraphFactory.openTransactionLog(graph);
userLogs.addLogProcessor(userLogName).setStartTime(startTime).setRetryAttempts(1).addProcessor((tx, txId, changes) -> {
assertEquals(instanceId, txId.getInstanceId());
// Just some reasonable upper bound
assertTrue(txId.getTransactionId() > 0 && txId.getTransactionId() < 100);
final Instant txTime = txId.getTransactionTime();
// Times should be within a second
assertTrue(String.format("tx timestamp %s not between start %s and end time %s", txTime, startTime, endTime), (txTime.isAfter(startTime) || txTime.equals(startTime)) && (txTime.isBefore(endTime) || txTime.equals(endTime)));
assertTrue(tx.containsRelationType("knows"));
assertTrue(tx.containsRelationType("weight"));
final EdgeLabel knows1 = tx.getEdgeLabel("knows");
final PropertyKey weight1 = tx.getPropertyKey("weight");
Instant txTimeMicro = txId.getTransactionTime();
int txNo;
if (txTimeMicro.isBefore(txTimes[1])) {
txNo = 1;
// v1 addition transaction
assertEquals(1, Iterables.size(changes.getVertices(Change.ADDED)));
assertEquals(0, Iterables.size(changes.getVertices(Change.REMOVED)));
assertEquals(1, Iterables.size(changes.getVertices(Change.ANY)));
assertEquals(2, Iterables.size(changes.getRelations(Change.ADDED)));
assertEquals(1, Iterables.size(changes.getRelations(Change.ADDED, knows1)));
assertEquals(1, Iterables.size(changes.getRelations(Change.ADDED, weight1)));
assertEquals(2, Iterables.size(changes.getRelations(Change.ANY)));
assertEquals(0, Iterables.size(changes.getRelations(Change.REMOVED)));
final JanusGraphVertex v = Iterables.getOnlyElement(changes.getVertices(Change.ADDED));
assertEquals(v1id, getId(v));
final VertexProperty<Float> p = Iterables.getOnlyElement(changes.getProperties(v, Change.ADDED, "weight"));
assertEquals(111.1, p.value().doubleValue(), 0.01);
assertEquals(1, Iterables.size(changes.getEdges(v, Change.ADDED, OUT)));
assertEquals(1, Iterables.size(changes.getEdges(v, Change.ADDED, BOTH)));
} else if (txTimeMicro.isBefore(txTimes[2])) {
txNo = 2;
// v2 addition transaction
assertEquals(1, Iterables.size(changes.getVertices(Change.ADDED)));
assertEquals(0, Iterables.size(changes.getVertices(Change.REMOVED)));
assertEquals(2, Iterables.size(changes.getVertices(Change.ANY)));
assertEquals(2, Iterables.size(changes.getRelations(Change.ADDED)));
assertEquals(1, Iterables.size(changes.getRelations(Change.ADDED, knows1)));
assertEquals(1, Iterables.size(changes.getRelations(Change.ADDED, weight1)));
assertEquals(2, Iterables.size(changes.getRelations(Change.ANY)));
assertEquals(0, Iterables.size(changes.getRelations(Change.REMOVED)));
final JanusGraphVertex v = Iterables.getOnlyElement(changes.getVertices(Change.ADDED));
assertEquals(v2id, getId(v));
final VertexProperty<Float> p = Iterables.getOnlyElement(changes.getProperties(v, Change.ADDED, "weight"));
assertEquals(222.2, p.value().doubleValue(), 0.01);
assertEquals(1, Iterables.size(changes.getEdges(v, Change.ADDED, OUT)));
assertEquals(1, Iterables.size(changes.getEdges(v, Change.ADDED, BOTH)));
} else if (txTimeMicro.isBefore(txTimes[3])) {
txNo = 3;
// v2 deletion transaction
assertEquals(0, Iterables.size(changes.getVertices(Change.ADDED)));
assertEquals(1, Iterables.size(changes.getVertices(Change.REMOVED)));
assertEquals(2, Iterables.size(changes.getVertices(Change.ANY)));
assertEquals(0, Iterables.size(changes.getRelations(Change.ADDED)));
assertEquals(2, Iterables.size(changes.getRelations(Change.REMOVED)));
assertEquals(1, Iterables.size(changes.getRelations(Change.REMOVED, knows1)));
assertEquals(1, Iterables.size(changes.getRelations(Change.REMOVED, weight1)));
assertEquals(2, Iterables.size(changes.getRelations(Change.ANY)));
final JanusGraphVertex v = Iterables.getOnlyElement(changes.getVertices(Change.REMOVED));
assertEquals(v2id, getId(v));
final VertexProperty<Float> p = Iterables.getOnlyElement(changes.getProperties(v, Change.REMOVED, "weight"));
assertEquals(222.2, p.value().doubleValue(), 0.01);
assertEquals(1, Iterables.size(changes.getEdges(v, Change.REMOVED, OUT)));
assertEquals(0, Iterables.size(changes.getEdges(v, Change.ADDED, BOTH)));
} else {
txNo = 4;
// v1 edge modification
assertEquals(0, Iterables.size(changes.getVertices(Change.ADDED)));
assertEquals(0, Iterables.size(changes.getVertices(Change.REMOVED)));
assertEquals(1, Iterables.size(changes.getVertices(Change.ANY)));
assertEquals(1, Iterables.size(changes.getRelations(Change.ADDED)));
assertEquals(1, Iterables.size(changes.getRelations(Change.REMOVED)));
assertEquals(1, Iterables.size(changes.getRelations(Change.REMOVED, knows1)));
assertEquals(2, Iterables.size(changes.getRelations(Change.ANY)));
final JanusGraphVertex v = Iterables.getOnlyElement(changes.getVertices(Change.ANY));
assertEquals(v1id, getId(v));
JanusGraphEdge e1 = Iterables.getOnlyElement(changes.getEdges(v, Change.REMOVED, Direction.OUT, "knows"));
assertFalse(e1.property("weight").isPresent());
assertEquals(v, e1.vertex(Direction.IN));
e1 = Iterables.getOnlyElement(changes.getEdges(v, Change.ADDED, Direction.OUT, "knows"));
assertEquals(44.4, e1.<Float>value("weight").doubleValue(), 0.01);
assertEquals(v, e1.vertex(Direction.IN));
}
// See only current state of graph in transaction
final JanusGraphVertex v11 = getV(tx, v1id);
assertNotNull(v11);
assertTrue(v11.isLoaded());
if (txNo != 2) {
// In the transaction that adds v2, v2 will be considered "loaded"
assertMissing(tx, v2id);
// assertTrue(txNo + " - " + v2, v2 == null || v2.isRemoved());
}
assertEquals(111.1, v11.<Float>value("weight").doubleValue(), 0.01);
assertCount(1, v11.query().direction(Direction.OUT).edges());
userLogCount.incrementAndGet();
}).build();
// wait
Thread.sleep(22000L);
recovery.shutdown();
long[] recoveryStats = ((StandardTransactionLogProcessor) recovery).getStatistics();
if (withLogFailure) {
assertEquals(1, recoveryStats[0]);
assertEquals(4, recoveryStats[1]);
} else {
assertEquals(5, recoveryStats[0]);
assertEquals(0, recoveryStats[1]);
}
userLogs.removeLogProcessor(userLogName);
userLogs.shutdown();
assertEquals(4, userLogCount.get());
}
use of org.janusgraph.graphdb.database.EdgeSerializer in project janusgraph by JanusGraph.
the class StandardJanusGraphTxTest method createTxWithMockedInternals.
private StandardJanusGraphTx createTxWithMockedInternals() {
StandardJanusGraph mockGraph = createMock(StandardJanusGraph.class);
TransactionConfiguration txConfig = createMock(TransactionConfiguration.class);
GraphDatabaseConfiguration gdbConfig = createMock(GraphDatabaseConfiguration.class);
TimestampProvider tsProvider = createMock(TimestampProvider.class);
Serializer mockSerializer = createMock(Serializer.class);
EdgeSerializer mockEdgeSerializer = createMock(EdgeSerializer.class);
IndexSerializer mockIndexSerializer = createMock(IndexSerializer.class);
RelationType relationType = createMock(RelationType.class);
IDManager idManager = createMock(IDManager.class);
PropertyKey propertyKey = createMock(PropertyKey.class);
DefaultSchemaMaker defaultSchemaMaker = createMock(DefaultSchemaMaker.class);
expect(mockGraph.getConfiguration()).andReturn(gdbConfig);
expect(mockGraph.isOpen()).andReturn(true).anyTimes();
expect(mockGraph.getDataSerializer()).andReturn(mockSerializer);
expect(mockGraph.getEdgeSerializer()).andReturn(mockEdgeSerializer);
expect(mockGraph.getIndexSerializer()).andReturn(mockIndexSerializer);
expect(mockGraph.getIDManager()).andReturn(idManager);
expect(gdbConfig.getTimestampProvider()).andReturn(tsProvider);
expect(txConfig.isSingleThreaded()).andReturn(true);
expect(txConfig.hasPreloadedData()).andReturn(false);
expect(txConfig.hasVerifyExternalVertexExistence()).andReturn(false);
expect(txConfig.hasVerifyInternalVertexExistence()).andReturn(false);
expect(txConfig.getVertexCacheSize()).andReturn(6);
expect(txConfig.isReadOnly()).andReturn(true);
expect(txConfig.getDirtyVertexSize()).andReturn(2);
expect(txConfig.getIndexCacheWeight()).andReturn(2L);
expect(txConfig.getGroupName()).andReturn(null);
expect(txConfig.getAutoSchemaMaker()).andReturn(defaultSchemaMaker);
expect(defaultSchemaMaker.makePropertyKey(isA(PropertyKeyMaker.class), notNull())).andReturn(propertyKey);
expect(relationType.isPropertyKey()).andReturn(false);
expect(propertyKey.isPropertyKey()).andReturn(true);
replayAll();
StandardJanusGraphTx partialMock = createMockBuilder(StandardJanusGraphTx.class).withConstructor(mockGraph, txConfig).addMockedMethod("getRelationType").createMock();
expect(partialMock.getRelationType("Foo")).andReturn(null);
expect(partialMock.getRelationType("Qux")).andReturn(propertyKey);
expect(partialMock.getRelationType("Baz")).andReturn(relationType);
replay(partialMock);
return partialMock;
}
Aggregations