private List<Entry> queryForEntries(AtomicQuery query, TransactionHandle txh) { ByteBuffer key = IDHandler.getKey(query.getVertexID()); List<Entry> entries = null; LimitTracker limit = new LimitTracker(query); boolean dirs[] = getAllowedDirections(query); if (query.hasEdgeTypeCondition()) { TitanType et = query.getTypeCondition(); if (!et.isNew()) { // Result set must be empty if TitanType is new ArrayList<Object> applicableConstraints = null; boolean isRange = false; if (query.hasConstraints()) { assert !et.isSimple(); TypeDefinition def = ((InternalTitanType) et).getDefinition(); String[] keysig = def.getKeySignature(); applicableConstraints = new ArrayList<Object>(keysig.length); Map<String, Object> constraints = query.getConstraints(); for (int i = 0; i < keysig.length; i++) { if (constraints.containsKey(keysig[i])) { Object iv = constraints.get(keysig[i]); applicableConstraints.add(iv); if (iv != null && (iv instanceof AtomicInterval) && ((AtomicInterval) iv).isRange()) { isRange = true; break; } } else break; } if (applicableConstraints.isEmpty()) applicableConstraints = null; } for (int dirID = 0; dirID < 4; dirID++) { if (dirs[dirID]) { if (applicableConstraints != null) { assert !applicableConstraints.isEmpty(); DataOutput start = serializer.getDataOutput(defaultOutputCapacity, true); DataOutput end = null; if (isRange) end = serializer.getDataOutput(defaultOutputCapacity, true); IDHandler.writeEdgeType(start, et.getID(), dirID, idManager); if (isRange) IDHandler.writeEdgeType(end, et.getID(), dirID, idManager); // Write all applicable key constraints for (Object iv : applicableConstraints) { if (iv instanceof AtomicInterval) { AtomicInterval interval = (AtomicInterval) iv; if (interval.isPoint()) { start.writeObject(interval.getStartPoint()); if (isRange) end.writeObject(interval.getStartPoint()); } else { assert isRange; assert interval.isRange(); ByteBuffer startColumn, endColumn; if (interval.getStartPoint() != null) { start.writeObject(interval.getStartPoint()); startColumn = start.getByteBuffer(); if (!interval.startInclusive()) startColumn = ByteBufferUtil.nextBiggerBuffer(startColumn); } else { assert interval.startInclusive(); startColumn = start.getByteBuffer(); } if (interval.getEndPoint() != null) { end.writeObject(interval.getEndPoint()); } else { assert interval.endInclusive(); } endColumn = end.getByteBuffer(); if (interval.endInclusive()) endColumn = ByteBufferUtil.nextBiggerBuffer(endColumn); entries = appendResults(key, startColumn, endColumn, entries, limit, txh); break; // redundant, this must be the last iteration because its a range } } else { assert iv == null || (iv instanceof TitanVertex); long id = 0; if (iv != null) id = ((TitanVertex) iv).getID(); VariableLong.writePositive(start, id); if (isRange) VariableLong.writePositive(end, id); } } if (!isRange) entries = appendResults(key, start.getByteBuffer(), entries, limit, txh); } else { ByteBuffer columnStart = IDHandler.getEdgeType(et.getID(), dirID, idManager); entries = appendResults(key, columnStart, entries, limit, txh); } } } } } else if (query.hasGroupCondition()) { int groupid = query.getGroupCondition().getID(); for (int dirID = 0; dirID < 4; dirID++) { if (dirs[dirID]) { ByteBuffer columnStart = IDHandler.getEdgeTypeGroup(groupid, dirID, idManager); entries = appendResults(key, columnStart, entries, limit, txh); } } } else { int lastDirID = -1; for (int dirID = 0; dirID <= 4; dirID++) { if ((dirID >= 4 || !dirs[dirID]) && lastDirID >= 0) { ByteBuffer columnStart = IDHandler.getEdgeTypeGroup(0, lastDirID, idManager); ByteBuffer columnEnd = IDHandler.getEdgeTypeGroup(idManager.getMaxGroupID() + 1, dirID - 1, idManager); entries = appendResults(key, columnStart, columnEnd, entries, limit, txh); lastDirID = -1; } if (dirID < 4) { if (dirs[dirID] && lastDirID == -1) lastDirID = dirID; } } } if (entries == null) return ImmutableList.of(); else return entries; }
protected void loadRelations( Iterable<Entry> entries, VertexRelationLoader loader, InternalTitanTransaction tx) { Map<String, TitanType> etCache = new HashMap<String, TitanType>(); TitanType titanType = null; for (Entry entry : entries) { ByteBuffer column = entry.getColumn(); int dirID = IDHandler.getDirectionID(column.get(column.position())); long etid = IDHandler.readEdgeType(column, idManager); if (titanType == null || titanType.getID() != etid) { titanType = getTypeFromID(etid, tx); } Object[] keys = null; if (!titanType.isSimple()) { TypeDefinition def = ((InternalTitanType) titanType).getDefinition(); String[] keysig = def.getKeySignature(); keys = new Object[keysig.length]; for (int i = 0; i < keysig.length; i++) keys[i] = readInline(column, getEdgeType(keysig[i], etCache, tx)); } long edgeid = 0; if (!titanType.isFunctional()) { edgeid = VariableLong.readPositive(column); } ByteBuffer value = entry.getValue(); if (titanType.isEdgeLabel()) { long nodeIDDiff = VariableLong.read(value); if (titanType.isFunctional()) edgeid = VariableLong.readPositive(value); assert edgeid > 0; long otherid = loader.getVertexId() + nodeIDDiff; assert dirID == 3 || dirID == 2; Direction dir = dirID == 3 ? Direction.IN : Direction.OUT; if (!tx.isDeletedRelation(edgeid)) loader.loadEdge(edgeid, (TitanLabel) titanType, dir, otherid); } else { assert titanType.isPropertyKey(); assert dirID == 0; TitanKey propType = ((TitanKey) titanType); Object attribute = null; if (hasGenericDataType(propType)) { attribute = serializer.readClassAndObject(value); } else { attribute = serializer.readObjectNotNull(value, propType.getDataType()); } assert attribute != null; if (titanType.isFunctional()) edgeid = VariableLong.readPositive(value); assert edgeid > 0; if (!tx.isDeletedRelation(edgeid)) loader.loadProperty(edgeid, propType, attribute); } // Read value inline edges if any if (!titanType.isSimple()) { TypeDefinition def = ((InternalTitanType) titanType).getDefinition(); // First create all keys buffered above String[] keysig = def.getKeySignature(); for (int i = 0; i < keysig.length; i++) { createInlineEdge(loader, getEdgeType(keysig[i], etCache, tx), keys[i]); } // value signature for (String str : def.getCompactSignature()) readLabel(loader, value, getEdgeType(str, etCache, tx)); // Third: read rest while (value.hasRemaining()) { TitanType type = (TitanType) tx.getExistingVertex(IDHandler.readInlineEdgeType(value, idManager)); readLabel(loader, value, type); } } } }