public TitanProperty setProperty(TitanVertex vertex, final TitanKey key, Object value) { Preconditions.checkNotNull(key); Preconditions.checkArgument( key.isUnique(Direction.OUT), "Not an out-unique key: %s", key.getName()); Lock uniqueLock = FakeLock.INSTANCE; try { if (config.hasVerifyUniqueness()) { // Acquire uniqueness lock, remove and add uniqueLock = getUniquenessLock(vertex, key, value); uniqueLock.lock(); vertex.removeProperty(key); } else { // Only delete in-memory InternalVertex v = (InternalVertex) vertex; for (InternalRelation r : v.it() .getAddedRelations( new Predicate<InternalRelation>() { @Override public boolean apply(@Nullable InternalRelation p) { return p.getType().equals(key); } })) { r.remove(); } } return addPropertyInternal(vertex, key, value); } finally { uniqueLock.unlock(); } }
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)); } } }
public TitanProperty addPropertyInternal(TitanVertex vertex, TitanKey key, Object value) { verifyWriteAccess(vertex); vertex = ((InternalVertex) vertex).it(); Preconditions.checkNotNull(key); value = AttributeUtil.verifyAttribute(key, value); Lock uniqueLock = FakeLock.INSTANCE; if (config.hasVerifyUniqueness() && (key.isUnique(Direction.OUT) || key.isUnique(Direction.IN))) uniqueLock = getUniquenessLock(vertex, key, value); uniqueLock.lock(); try { // Check uniqueness if (config.hasVerifyUniqueness()) { if (key.isUnique(Direction.OUT)) { Preconditions.checkArgument( Iterables.isEmpty( query(vertex).includeHidden().type(key).direction(Direction.OUT).properties()), "An property with the given key already exists on the vertex and the property key is defined as out-unique"); } if (key.isUnique(Direction.IN)) { Preconditions.checkArgument( Iterables.isEmpty(getVertices(key, value)), "The given value is already used as a property and the property key is defined as in-unique"); } } StandardProperty prop = new StandardProperty( temporaryID.decrementAndGet(), key, (InternalVertex) vertex, value, ElementLifeCycle.New); if (config.hasAssignIDsImmediately()) graph.assignID(prop); connectRelation(prop); return prop; } finally { uniqueLock.unlock(); } }
@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; }
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 TitanVertex getVertex(TitanKey key, Object attribute) { Preconditions.checkArgument( key.isUnique(Direction.IN), "Key is not uniquely associated to value [%s]", key.getName()); return Iterables.getOnlyElement(getVertices(key, attribute), null); }
@Override public TitanProperty addProperty(TitanVertex vertex, TitanKey key, Object value) { if (key.isUnique(Direction.OUT)) return setProperty(vertex, key, value); else return addPropertyInternal(vertex, key, value); }
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()); }