Пример #1
0
    @Override
    public Reservation validate(Iterable<NodePropertyUpdate> updates)
        throws IOException, IndexCapacityExceededException {
      int insertionsCount = 0;
      for (NodePropertyUpdate update : updates) {
        // Only count additions and updates, since removals will not affect the size of the index
        // until it is merged. Each update is in fact atomic (delete + add).
        if (update.getUpdateMode() == UpdateMode.ADDED
            || update.getUpdateMode() == UpdateMode.CHANGED) {
          insertionsCount++;
        }
      }

      writer.reserveInsertions(insertionsCount);

      final int insertions = insertionsCount;
      return new Reservation() {
        boolean released;

        @Override
        public void release() {
          if (released) {
            throw new IllegalStateException(
                "Reservation was already released. "
                    + "Previously reserved "
                    + insertions
                    + " insertions");
          }
          writer.removeReservedInsertions(insertions);
          released = true;
        }
      };
    }
  @Override
  public void process(NodePropertyUpdate update) {
    // build uniqueness verification state
    switch (update.getUpdateMode()) {
      case ADDED:
        propertyValueDiffSet(referenceCount, update.getValueAfter()).add(update.getNodeId());
        break;
      case CHANGED:
        propertyValueDiffSet(referenceCount, update.getValueBefore()).remove(update.getNodeId());
        propertyValueDiffSet(referenceCount, update.getValueAfter()).add(update.getNodeId());
        break;
      case REMOVED:
        propertyValueDiffSet(referenceCount, update.getValueBefore()).remove(update.getNodeId());
        break;
      default:
        throw new UnsupportedOperationException();
    }

    // do not flush update before close
    updates.add(update);
  }
Пример #3
0
 @Override
 public void process(NodePropertyUpdate update)
     throws IOException, IndexCapacityExceededException {
   switch (update.getUpdateMode()) {
     case ADDED:
       if (inRecovery) {
         addRecovered(update.getNodeId(), update.getValueAfter());
       } else {
         add(update.getNodeId(), update.getValueAfter());
       }
       break;
     case CHANGED:
       change(update.getNodeId(), update.getValueAfter());
       break;
     case REMOVED:
       LuceneIndexAccessor.this.remove(update.getNodeId());
       break;
     default:
       throw new UnsupportedOperationException();
   }
 }
Пример #4
0
  @Test
  public void shouldCreateEqualNodePropertyUpdatesOnRecoveryOfCreatedNode() throws Exception {
    /* There was an issue where recovering a tx where a node with a label and a property
     * was created resulted in two exact copies of NodePropertyUpdates. */

    // GIVEN
    long nodeId = 1;
    int labelId = 5, propertyKeyId = 7;
    NodePropertyUpdate expectedUpdate =
        NodePropertyUpdate.add(nodeId, propertyKeyId, "Neo", new long[] {labelId});

    // -- an index
    long ruleId = 0;
    WriteTransaction tx = newWriteTransaction(NO_INDEXING);
    SchemaRule rule = IndexRule.indexRule(ruleId, labelId, propertyKeyId, PROVIDER_DESCRIPTOR);
    tx.createSchemaRule(rule);
    prepareAndCommit(tx);

    // -- and a tx creating a node with that label and property key
    IndexingService index = mock(IndexingService.class);
    CommandCapturingVisitor commandCapturingVisitor = new CommandCapturingVisitor();
    tx = newWriteTransaction(index, commandCapturingVisitor);
    tx.nodeCreate(nodeId);
    tx.addLabelToNode(labelId, nodeId);
    tx.nodeAddProperty(nodeId, propertyKeyId, "Neo");
    prepareAndCommit(tx);
    verify(index, times(1)).updateIndexes(argThat(matchesAll(expectedUpdate)));
    reset(index);

    // WHEN
    // -- later recovering that tx, there should be only one update
    tx = newWriteTransaction(index);
    commandCapturingVisitor.injectInto(tx);
    prepareAndCommitRecovered(tx);
    verify(index, times(1)).updateIndexes(argThat(matchesAll(expectedUpdate)));
  }
 private NodePropertyUpdate add(long nodeId, Object propertyValue) {
   return NodePropertyUpdate.add(nodeId, propertyKeyId, propertyValue, new long[] {labelId});
 }