private static void writeAttribute(DataOutput out, TitanProperty property) { Object attribute = property.getAttribute(); TitanKey key = (TitanKey) property.getType(); assert attribute != null; assert key.getDataType().isInstance(attribute); if (hasGenericDataType(key)) { out.writeClassAndObject(attribute); } else { out.writeObjectNotNull(attribute); } }
private Object readInline(ByteBuffer read, TitanType type) { if (type.isPropertyKey()) { TitanKey proptype = ((TitanKey) type); if (hasGenericDataType(proptype)) return serializer.readClassAndObject(read); else return serializer.readObject(read, proptype.getDataType()); } else { assert type.isEdgeLabel(); Long id = Long.valueOf(VariableLong.readPositive(read)); if (id.longValue() == 0) return null; else return id; } }
private void lockKeyedProperty(TitanProperty prop, StoreMutator mutator) throws StorageException { TitanKey pt = prop.getPropertyKey(); assert pt.isSimple(); if (pt.hasIndex() && pt.isUnique()) { if (prop.isNew()) { mutator.acquireIndexLock(getIndexKey(prop.getAttribute()), getKeyedIndexColumn(pt), null); } else { assert prop.isRemoved(); mutator.acquireIndexLock( getIndexKey(prop.getAttribute()), getKeyedIndexColumn(pt), getIndexValue(prop)); } } }
private void addIndexEntry(TitanProperty prop, StoreMutator mutator) throws StorageException { TitanKey pt = prop.getPropertyKey(); assert pt.isSimple(); if (pt.hasIndex()) { if (pt.isUnique()) { mutator.mutateIndex( getIndexKey(prop.getAttribute()), Lists.newArrayList(new Entry(getKeyedIndexColumn(pt), getIndexValue(prop))), null); } else { mutator.mutateIndex( getIndexKey(prop.getAttribute()), Lists.newArrayList(new Entry(getIndexColumn(pt, prop.getID()), getIndexValue(prop))), null); } } }
@Override public long[] indexRetrieval(Object key, TitanKey pt, InternalTitanTransaction tx) { Preconditions.checkArgument( pt.isSimple(), "Currently, only simple properties are supported for index retrieval"); Preconditions.checkArgument( pt.hasIndex(), "Cannot retrieve for given property key - it does not have an index"); long[] vertices = null; Preconditions.checkArgument( pt.getDataType().isInstance(key), "Specified object is incompatible with property data type [" + pt.getName() + "]"); for (int readAttempt = 0; readAttempt < maxReadRetryAttempts; readAttempt++) { try { if (pt.isUnique()) { ByteBuffer value = propertyIndex.get(getIndexKey(key), getKeyedIndexColumn(pt), tx.getTxHandle()); if (value != null) { vertices = new long[1]; vertices[0] = VariableLong.readPositive(value); } } else { ByteBuffer startColumn = VariableLong.positiveByteBuffer(pt.getID()); List<Entry> entries = propertyIndex.getSlice( getIndexKey(key), startColumn, ByteBufferUtil.nextBiggerBuffer(startColumn), tx.getTxHandle()); vertices = new long[entries.size()]; int i = 0; for (Entry ent : entries) { vertices[i++] = VariableLong.readPositive(ent.getValue()); } } break; } catch (StorageException e) { if (e instanceof TemporaryStorageException) { if (readAttempt < maxReadRetryAttempts - 1) temporaryStorageException(e); else throw readException(e, maxReadRetryAttempts); } else throw readException(e); } } if (vertices == null) return new long[0]; else return vertices; }
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); } } } }
private ByteBuffer getIndexColumn(TitanKey type, long propertyID) { assert !type.isUnique(); return VariableLong.positiveByteBuffer(new long[] {type.getID(), propertyID}); }
private ByteBuffer getKeyedIndexColumn(TitanKey type) { assert type.isUnique(); return VariableLong.positiveByteBuffer(type.getID()); }
private static final boolean hasGenericDataType(TitanKey key) { return key.getDataType().equals(Object.class); }