@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); }
@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(); } }
@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}); }