Exemplo n.º 1
0
  private void writeInlineEdge(
      DataOutput out, InternalRelation edge, TitanType type, boolean writeEdgeType) {
    assert type.isSimple();
    assert writeEdgeType
        || type.isEdgeLabel()
        || (type.isPropertyKey() && !hasGenericDataType((TitanKey) type));

    if (edge == null) {
      assert !writeEdgeType;
      if (type.isPropertyKey()) {
        out.writeObject(null);
      } else {
        assert type.isEdgeLabel();
        VariableLong.writePositive(out, 0);
      }
    } else {
      if (writeEdgeType) {
        IDHandler.writeInlineEdgeType(out, type.getID(), idManager);
      }
      if (edge.isProperty()) {
        Object attribute = ((TitanProperty) edge).getAttribute();
        if (hasGenericDataType((TitanKey) type)) out.writeClassAndObject(attribute);
        else out.writeObject(attribute);
      } else {
        assert edge.isUnidirected() && edge.isEdge();
        VariableLong.writePositive(out, edge.getVertex(1).getID());
      }
    }
  }
Exemplo n.º 2
0
  private <N extends InternalTitanVertex> void persist(
      ListMultimap<N, InternalRelation> mutatedEdges,
      Map<TitanType, TypeSignature> signatures,
      InternalTitanTransaction tx,
      StoreMutator mutator)
      throws StorageException {
    assert mutatedEdges != null && !mutatedEdges.isEmpty();

    Collection<N> vertices = mutatedEdges.keySet();
    //		if (sortNodes) {
    //			List<N> sortedvertices = new ArrayList<N>(vertices);
    //			Collections.sort(sortedvertices, new Comparator<N>(){
    //
    //				@Override
    //				public int compare(N o1, N o2) {
    //					assert o1.getID()!=o2.getID();
    //					if (o1.getID()<o2.getID()) return -1;
    //					else return 1;
    //				}
    //
    //			});
    //			vertices=sortedvertices;
    //		}

    for (N node : vertices) {
      List<InternalRelation> edges = mutatedEdges.get(node);
      List<Entry> additions = new ArrayList<Entry>(edges.size());
      List<ByteBuffer> deletions = new ArrayList<ByteBuffer>(Math.max(10, edges.size() / 10));
      List<TitanProperty> properties = new ArrayList<TitanProperty>();
      for (InternalRelation edge : edges) {
        if (edge.isRemoved()) {
          if (edge.isProperty()) {
            deleteIndexEntry((TitanProperty) edge, mutator);
          }
          deletions.add(getEntry(tx, edge, node, signatures, true).getColumn());
        } else {
          assert edge.isNew();
          if (edge.isProperty()) properties.add((TitanProperty) edge);
          additions.add(getEntry(tx, edge, node, signatures));
        }
      }
      mutator.mutateEdges(IDHandler.getKey(node.getID()), additions, deletions);
      // Persist property index for retrieval
      for (TitanProperty prop : properties) {
        addIndexEntry(prop, mutator);
      }
    }
  }
Exemplo n.º 3
0
  private void assignIDs(Collection<InternalRelation> addedEdges, InternalTitanTransaction tx) {
    for (InternalRelation edge : addedEdges) {
      if (edge.isRemoved()) continue;
      if (edge.hasID()) continue;

      for (int i = 0; i < edge.getArity(); i++) {
        InternalTitanVertex node = edge.getVertex(i);
        if (!node.hasID()) {
          assert node.isNew();
          assignID(node);
        }
      }
      assert !edge.hasID();
      assignID(edge);
    }
  }
Exemplo n.º 4
0
 private void writeInlineEdge(DataOutput out, InternalRelation edge) {
   assert edge != null;
   writeInlineEdge(out, edge, edge.getType(), true);
 }
Exemplo n.º 5
0
  private Entry getEntry(
      InternalTitanTransaction tx,
      InternalRelation edge,
      InternalTitanVertex perspective,
      Map<TitanType, TypeSignature> signatures,
      boolean columnOnly) {
    TitanType et = edge.getType();
    long etid = et.getID();

    int dirID;
    if (edge.isProperty()) {
      dirID = 0;
    } else if (edge.getVertex(0).equals(perspective)) {
      // Out TitanRelation
      assert edge.isDirected() || edge.isUnidirected();
      dirID = 2;
    } else {
      // In TitanRelation
      assert !edge.isUnidirected() && edge.getVertex(1).equals(perspective);
      dirID = 3;
    }

    int etIDLength = IDHandler.edgeTypeLength(etid, idManager);

    ByteBuffer column = null, value = null;
    if (et.isSimple()) {
      if (et.isFunctional()) {
        column = ByteBuffer.allocate(etIDLength);
        IDHandler.writeEdgeType(column, etid, dirID, idManager);
      } else {
        column = ByteBuffer.allocate(etIDLength + VariableLong.positiveLength(edge.getID()));
        IDHandler.writeEdgeType(column, etid, dirID, idManager);
        VariableLong.writePositive(column, edge.getID());
      }
      column.flip();
      if (!columnOnly) {
        if (edge.isEdge()) {
          long nodeIDDiff =
              ((TitanEdge) edge).getOtherVertex(perspective).getID() - perspective.getID();
          int nodeIDDiffLength = VariableLong.length(nodeIDDiff);
          if (et.isFunctional()) {
            value =
                ByteBuffer.allocate(nodeIDDiffLength + VariableLong.positiveLength(edge.getID()));
            VariableLong.write(value, nodeIDDiff);
            VariableLong.writePositive(value, edge.getID());
          } else {
            value = ByteBuffer.allocate(nodeIDDiffLength);
            VariableLong.write(value, nodeIDDiff);
          }
          value.flip();
        } else {
          assert edge.isProperty();
          DataOutput out = serializer.getDataOutput(defaultOutputCapacity, true);
          // Write object
          writeAttribute(out, (TitanProperty) edge);
          if (et.isFunctional()) {
            VariableLong.writePositive(out, edge.getID());
          }
          value = out.getByteBuffer();
        }
      }
    } else {
      TypeSignature ets = getSignature(tx, et, signatures);

      InternalRelation[] keys = new InternalRelation[ets.keyLength()],
          values = new InternalRelation[ets.valueLength()];
      List<InternalRelation> rest = new ArrayList<InternalRelation>();
      ets.sort(edge.getRelations(SimpleAtomicQuery.queryAll(edge), false), keys, values, rest);

      DataOutput out = serializer.getDataOutput(defaultOutputCapacity, true);
      IDHandler.writeEdgeType(out, etid, dirID, idManager);

      for (int i = 0; i < keys.length; i++) writeInlineEdge(out, keys[i], ets.getKeyType(i));

      if (!et.isFunctional()) {
        VariableLong.writePositive(out, edge.getID());
      }
      column = out.getByteBuffer();

      if (!columnOnly) {
        out = serializer.getDataOutput(defaultOutputCapacity, true);

        if (edge.isEdge()) {
          long nodeIDDiff =
              ((TitanEdge) edge).getOtherVertex(perspective).getID() - perspective.getID();
          VariableLong.write(out, nodeIDDiff);
        } else {
          assert edge.isProperty();
          writeAttribute(out, (TitanProperty) edge);
        }

        if (et.isFunctional()) {
          assert edge.isEdge();
          VariableLong.writePositive(out, edge.getID());
        }
        for (int i = 0; i < values.length; i++)
          writeInlineEdge(out, values[i], ets.getValueType(i));
        for (InternalRelation v : rest) writeInlineEdge(out, v);
        value = out.getByteBuffer();
      }
    }
    return new Entry(column, value);
  }
Exemplo n.º 6
0
  @Override
  public void save(
      final Collection<InternalRelation> addedRelations,
      final Collection<InternalRelation> deletedRelations,
      final InternalTitanTransaction tx)
      throws StorageException {
    // Setup
    log.debug(
        "Saving transaction. Added {}, removed {}", addedRelations.size(), deletedRelations.size());
    final Map<TitanType, TypeSignature> signatures = new HashMap<TitanType, TypeSignature>();
    final TransactionHandle txh = tx.getTxHandle();

    final StoreMutator mutator = getStoreMutator(txh);
    final boolean acquireLocks = tx.getTxConfiguration().hasAcquireLocks();

    // 1. Assign TitanVertex IDs
    assignIDs(addedRelations, tx);

    for (int saveAttempt = 0; saveAttempt < maxWriteRetryAttempts; saveAttempt++) {
      //        while (true) { //Indefinite loop, broken if no exception occurs, otherwise retried
      // or failed immediately
      try {
        // 2. Collect deleted edges
        ListMultimap<InternalTitanVertex, InternalRelation> mutations = ArrayListMultimap.create();
        if (deletedRelations != null && !deletedRelations.isEmpty()) {
          for (InternalRelation del : deletedRelations) {
            assert del.isRemoved();
            for (int pos = 0; pos < del.getArity(); pos++) {
              InternalTitanVertex node = del.getVertex(pos);
              if (pos == 0 || !del.isUnidirected()) {
                mutations.put(node, del);
              }
              if (pos == 0
                  && acquireLocks
                  && del.getType().isFunctional()
                  && ((InternalTitanType) del.getType()).isFunctionalLocking()) {
                Entry entry = getEntry(tx, del, node, signatures);
                mutator.acquireEdgeLock(
                    IDHandler.getKey(node.getID()), entry.getColumn(), entry.getValue());
              }
            }
            if (acquireLocks && del.isProperty()) {
              lockKeyedProperty((TitanProperty) del, mutator);
            }
          }
        }

        ListMultimap<InternalTitanType, InternalRelation> simpleEdgeTypes = null;
        ListMultimap<InternalTitanType, InternalRelation> otherEdgeTypes = null;

        // 3. Sort Added Edges
        for (InternalRelation edge : addedRelations) {
          if (edge.isRemoved()) continue;
          assert edge.isNew();

          TitanType et = edge.getType();

          // Give special treatment to edge type definitions
          if (SystemTypeManager.prepersistedSystemTypes.contains(et)) {
            assert edge.getVertex(0) instanceof InternalTitanType;
            InternalTitanType node = (InternalTitanType) edge.getVertex(0);
            assert node.hasID();
            if (node.isSimple()) {
              if (simpleEdgeTypes == null) simpleEdgeTypes = ArrayListMultimap.create();
              simpleEdgeTypes.put(node, edge);
            } else {
              if (otherEdgeTypes == null) otherEdgeTypes = ArrayListMultimap.create();
              otherEdgeTypes.put(node, edge);
            }
          } else { // STANDARD TitanRelation
            assert (edge.getArity() == 1 && edge.isProperty())
                || (edge.getArity() == 2 && edge.isEdge());
            for (int pos = 0; pos < edge.getArity(); pos++) {
              InternalTitanVertex node = edge.getVertex(pos);
              assert node.hasID();
              if (pos == 0 || !edge.isUnidirected()) {
                mutations.put(node, edge);
              }
              if (pos == 0
                  && acquireLocks
                  && edge.getType().isFunctional()
                  && !node.isNew()
                  && ((InternalTitanType) edge.getType()).isFunctionalLocking()) {
                Entry entry = getEntry(tx, edge, node, signatures, true);
                mutator.acquireEdgeLock(IDHandler.getKey(node.getID()), entry.getColumn(), null);
              }
            }
          }
          if (acquireLocks && edge.isProperty()) {
            lockKeyedProperty((TitanProperty) edge, mutator);
          }
        }

        // 3. Persist
        if (simpleEdgeTypes != null) persist(simpleEdgeTypes, signatures, tx, mutator);
        if (otherEdgeTypes != null) persist(otherEdgeTypes, signatures, tx, mutator);
        mutator.flush();

        // Commit saved EdgeTypes to TypeManager
        if (simpleEdgeTypes != null) commitEdgeTypes(simpleEdgeTypes.keySet());
        if (otherEdgeTypes != null) commitEdgeTypes(otherEdgeTypes.keySet());

        if (!mutations.isEmpty()) persist(mutations, signatures, tx, mutator);
        mutator.flush();

        // Successfully completed - return to break out of loop
        break;
      } catch (Throwable e) {
        if (e instanceof TemporaryStorageException) {
          if (saveAttempt < maxWriteRetryAttempts - 1) temporaryStorageException(e);
          else
            throw new PermanentStorageException(
                "Tried committing "
                    + maxWriteRetryAttempts
                    + " times on temporary exception without success",
                e);
        } else if (e instanceof StorageException) {
          throw (StorageException) e;
        } else {
          throw new PermanentStorageException(
              "Unidentified exception occurred during persistence", e);
        }
      }
    }
  }