mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
[indexes][refactoring] combine add/remove/update processors into single UpdatedEntryProcessor
+ 3 different processors were used during diff(old,new) calculation, to report added/updated/removed entries -> actual processing of all 3 categories is quite similar, so I replace 3 processors with 1 `UpdatedEntryProcessor` with an additional `UpdateKind` enum arg. GitOrigin-RevId: 53b1121ee1cb0899c87de17a9148b0b51029dd45
This commit is contained in:
committed by
intellij-monorepo-bot
parent
bb7fd0b10c
commit
13dfa850c0
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.stubs;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -10,8 +10,7 @@ import com.intellij.util.indexing.FileBasedIndexEx;
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
import com.intellij.util.indexing.impl.DirectInputDataDiffBuilder;
|
||||
import com.intellij.util.indexing.impl.IndexDebugProperties;
|
||||
import com.intellij.util.indexing.impl.KeyValueUpdateProcessor;
|
||||
import com.intellij.util.indexing.impl.RemovedKeyProcessor;
|
||||
import com.intellij.util.indexing.impl.UpdatedEntryProcessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -28,20 +27,15 @@ final class StubCumulativeInputDiffBuilder extends DirectInputDataDiffBuilder<In
|
||||
|
||||
@Override
|
||||
public boolean differentiate(@NotNull Map<Integer, SerializedStubTree> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Integer> removeProcessor) throws StorageException
|
||||
{
|
||||
return differentiate(newData, addProcessor, updateProcessor, removeProcessor, false);
|
||||
@NotNull UpdatedEntryProcessor<? super Integer, ? super SerializedStubTree> changesProcessor) throws StorageException {
|
||||
return differentiate(newData, changesProcessor, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dryRun if true, won't update the stub indices
|
||||
*/
|
||||
public boolean differentiate(@NotNull Map<Integer, SerializedStubTree> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Integer> removeProcessor,
|
||||
@NotNull UpdatedEntryProcessor<? super Integer, ? super SerializedStubTree> changesProcessor,
|
||||
boolean dryRun) throws StorageException {
|
||||
if (FileBasedIndexEx.TRACE_STUB_INDEX_UPDATES) {
|
||||
LOG.info((dryRun ? "[dry run]" : "") + "differentiate: inputId=" + myInputId +
|
||||
@@ -69,9 +63,9 @@ final class StubCumulativeInputDiffBuilder extends DirectInputDataDiffBuilder<In
|
||||
",newStubLen=" + newSerializedStubTree.myIndexedStubByteLength);
|
||||
}
|
||||
}
|
||||
removeProcessor.process(myInputId, myInputId);
|
||||
changesProcessor.removed(myInputId, myInputId);
|
||||
}
|
||||
addProcessor.process(myInputId, newSerializedStubTree, myInputId);
|
||||
changesProcessor.added(myInputId, newSerializedStubTree, myInputId);
|
||||
if (!dryRun) updateStubIndices(newSerializedStubTree);
|
||||
}
|
||||
else {
|
||||
@@ -81,7 +75,7 @@ final class StubCumulativeInputDiffBuilder extends DirectInputDataDiffBuilder<In
|
||||
}
|
||||
return false; // ?????????
|
||||
}
|
||||
removeProcessor.process(myInputId, myInputId);
|
||||
changesProcessor.removed(myInputId, myInputId);
|
||||
if (!dryRun) updateStubIndices(null);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -92,19 +92,19 @@ public abstract class StubIndexEx extends StubIndex {
|
||||
fileId,
|
||||
index.getExtension().getName(),
|
||||
|
||||
(addedEntriesProcessor, updatedEntriesProcessor, removedEntriesProcessor) -> {
|
||||
(changedEntriesProcessor) -> {
|
||||
|
||||
boolean modified = false;
|
||||
for (K oldKey : oldKeys) {
|
||||
if (!newKeys.contains(oldKey)) {
|
||||
removedEntriesProcessor.process(oldKey, fileId);
|
||||
changedEntriesProcessor.removed(oldKey, fileId);
|
||||
if (!modified) modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (K newKey : newKeys) {
|
||||
if (!oldKeys.contains(newKey)) {
|
||||
addedEntriesProcessor.process(newKey, null, fileId);
|
||||
changedEntriesProcessor.added(newKey, null, fileId);
|
||||
if (!modified) modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,27 +99,25 @@ public class SingleEntryIndexForwardIndexAccessor<V> extends AbstractMapForwardI
|
||||
|
||||
@Override
|
||||
public boolean differentiate(@NotNull Map<Integer, V> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super V> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super V> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Integer> removeProcessor) throws StorageException {
|
||||
@NotNull UpdatedEntryProcessor<? super Integer, ? super V> changesProcessor) throws StorageException {
|
||||
boolean newValueExists = !newData.isEmpty();
|
||||
V newValue = ContainerUtil.getFirstItem(newData.values());
|
||||
if (myContainsValue) {
|
||||
if (!newValueExists) {
|
||||
removeProcessor.process(myInputId, myInputId);
|
||||
changesProcessor.removed(myInputId, myInputId);
|
||||
return true;
|
||||
}
|
||||
else if (Comparing.equal(myCurrentValue, newValue)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
updateProcessor.process(myInputId, newValue, myInputId);
|
||||
changesProcessor.updated(myInputId, newValue, myInputId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (newValueExists) {
|
||||
addProcessor.process(myInputId, newValue, myInputId);
|
||||
changesProcessor.added(myInputId, newValue, myInputId);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -223,7 +223,7 @@ final class PerFileElementTypeStubModificationTracker implements StubIndexImpl.F
|
||||
}
|
||||
final Stub stub = StubTreeBuilder.buildStubTree(fileContent);
|
||||
Map<Integer, SerializedStubTree> serializedStub = stub == null ? Collections.emptyMap() : stubIndexer.map(fileContent);
|
||||
if (diffBuilder.differentiate(serializedStub, (__, ___, ____) -> { }, (__, ___, ____) -> { }, (__, ___) -> { }, true)) {
|
||||
if (diffBuilder.differentiate(serializedStub, (__, ___, ____, _____) -> { }, true)) {
|
||||
registerModificationFor(info.type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4306,12 +4306,6 @@ f:com.intellij.util.indexing.impl.CollectionDataExternalizer
|
||||
- <init>(com.intellij.util.io.DataExternalizer):V
|
||||
- read(java.io.DataInput):java.util.Collection
|
||||
- save(java.io.DataOutput,java.util.Collection):V
|
||||
f:com.intellij.util.indexing.impl.EmptyInputDataDiffBuilder
|
||||
- <init>(I):V
|
||||
- differentiate(java.util.Map,com.intellij.util.indexing.impl.KeyValueUpdateProcessor,com.intellij.util.indexing.impl.KeyValueUpdateProcessor,com.intellij.util.indexing.impl.RemovedKeyProcessor):Z
|
||||
- getKeys():java.util.Collection
|
||||
- s:processAllKeyValuesAsAdded(I,java.util.Map,com.intellij.util.indexing.impl.KeyValueUpdateProcessor):Z
|
||||
- s:processAllKeyValuesAsRemoved(I,java.util.Map,com.intellij.util.indexing.impl.RemovedKeyProcessor):Z
|
||||
com.intellij.util.indexing.impl.IndexStorage
|
||||
- java.io.Closeable
|
||||
- java.io.Flushable
|
||||
@@ -4336,18 +4330,10 @@ f:com.intellij.util.indexing.impl.InputIndexDataExternalizer
|
||||
- <init>(com.intellij.util.io.KeyDescriptor,com.intellij.util.indexing.IndexId):V
|
||||
- read(java.io.DataInput):java.util.Collection
|
||||
- save(java.io.DataOutput,java.util.Collection):V
|
||||
com.intellij.util.indexing.impl.KeyValueUpdateProcessor
|
||||
- a:process(java.lang.Object,java.lang.Object,I):V
|
||||
c:com.intellij.util.indexing.impl.MapInputDataDiffBuilder
|
||||
- <init>(I,java.util.Map):V
|
||||
- differentiate(java.util.Map,com.intellij.util.indexing.impl.KeyValueUpdateProcessor,com.intellij.util.indexing.impl.KeyValueUpdateProcessor,com.intellij.util.indexing.impl.RemovedKeyProcessor):Z
|
||||
- getKeys():java.util.Collection
|
||||
*f:com.intellij.util.indexing.impl.MapReduceIndexMappingException
|
||||
- java.lang.RuntimeException
|
||||
- <init>(java.lang.Throwable,java.lang.Class):V
|
||||
- getClassToBlame():java.lang.Class
|
||||
com.intellij.util.indexing.impl.RemovedKeyProcessor
|
||||
- a:process(java.lang.Object,I):V
|
||||
com.intellij.util.indexing.impl.ValueSerializationProblemReporter
|
||||
- a:reportProblem(java.lang.Exception):V
|
||||
com.intellij.util.indexing.impl.forward.ForwardIndex
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
package com.intellij.util.indexing.impl;
|
||||
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class EmptyInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuilder<Key, Value> {
|
||||
public EmptyInputDataDiffBuilder(int inputId) {
|
||||
super(inputId);
|
||||
@@ -20,21 +22,19 @@ public final class EmptyInputDataDiffBuilder<Key, Value> extends DirectInputData
|
||||
|
||||
@Override
|
||||
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException {
|
||||
return processAllKeyValuesAsAdded(myInputId, newData, addProcessor);
|
||||
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException {
|
||||
return processAllKeyValuesAsAdded(myInputId, newData, changesProcessor);
|
||||
}
|
||||
|
||||
public static <Key, Value> boolean processAllKeyValuesAsAdded(int inputId,
|
||||
@NotNull Map<Key, Value> addedData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor)
|
||||
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor)
|
||||
throws StorageException {
|
||||
boolean[] anyAdded = {false};
|
||||
try {
|
||||
addedData.forEach((key, value) -> {
|
||||
try {
|
||||
addProcessor.process(key, value, inputId);
|
||||
changesProcessor.added(key, value, inputId);
|
||||
}
|
||||
catch (StorageException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -54,10 +54,11 @@ public final class EmptyInputDataDiffBuilder<Key, Value> extends DirectInputData
|
||||
|
||||
public static <Key, Value> boolean processAllKeyValuesAsRemoved(int inputId,
|
||||
@NotNull Map<Key, Value> removedData,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removedProcessor) throws StorageException {
|
||||
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor)
|
||||
throws StorageException {
|
||||
boolean anyRemoved = false;
|
||||
for (Key key : removedData.keySet()) {
|
||||
removedProcessor.process(key, inputId);
|
||||
changesProcessor.removed(key, inputId);
|
||||
anyRemoved = true;
|
||||
}
|
||||
return anyRemoved;
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.indexing.impl;
|
||||
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
@@ -34,7 +20,5 @@ public abstract class InputDataDiffBuilder<Key, Value> {
|
||||
* @return false if there is no difference and true otherwise
|
||||
*/
|
||||
public abstract boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException;
|
||||
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException;
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.util.indexing.impl;
|
||||
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
|
||||
public interface KeyValueUpdateProcessor<Key, Value> {
|
||||
void process(Key key, Value value, int inputId) throws StorageException;
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.indexing.impl;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -12,6 +13,7 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuilder<Key, Value> {
|
||||
private final @NotNull Map<Key, Value> myMap;
|
||||
|
||||
@@ -22,14 +24,12 @@ public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuil
|
||||
|
||||
@Override
|
||||
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException {
|
||||
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException {
|
||||
if (myMap.isEmpty()) {
|
||||
return EmptyInputDataDiffBuilder.processAllKeyValuesAsAdded(myInputId, newData, addProcessor);
|
||||
return EmptyInputDataDiffBuilder.processAllKeyValuesAsAdded(myInputId, newData, changesProcessor);
|
||||
}
|
||||
if (newData.isEmpty()) {
|
||||
return EmptyInputDataDiffBuilder.processAllKeyValuesAsRemoved(myInputId, myMap, removeProcessor);
|
||||
return EmptyInputDataDiffBuilder.processAllKeyValuesAsRemoved(myInputId, myMap, changesProcessor);
|
||||
}
|
||||
|
||||
int added = 0;
|
||||
@@ -42,11 +42,11 @@ public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuil
|
||||
Value newValue = newData.get(key);
|
||||
if (!Comparing.equal(oldValue, newValue) || (newValue == null && !newData.containsKey(key))) {
|
||||
if (newData.containsKey(key)) {
|
||||
updateProcessor.process(key, newValue, myInputId);
|
||||
changesProcessor.updated(key, newValue, myInputId);
|
||||
updated++;
|
||||
}
|
||||
else {
|
||||
removeProcessor.process(key, myInputId);
|
||||
changesProcessor.removed(key, myInputId);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuil
|
||||
for (Map.Entry<Key, Value> e : newData.entrySet()) {
|
||||
final Key newKey = e.getKey();
|
||||
if (!myMap.containsKey(newKey)) {
|
||||
addProcessor.process(newKey, e.getValue(), myInputId);
|
||||
changesProcessor.added(newKey, e.getValue(), myInputId);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,16 +313,11 @@ public abstract class MapReduceIndex<Key, Value, Input> implements InvertedIndex
|
||||
inputId,
|
||||
indexId(),
|
||||
|
||||
(addedEntriesProcessor, updatedEntriesProcessor, removedEntriesProcessor) -> {
|
||||
(changedEntriesProcessor) -> {
|
||||
try {
|
||||
InputDataDiffBuilder<Key, Value> diffBuilder = getKeysDiffBuilder(inputId);
|
||||
Map<Key, Value> newData = inputData.getKeyValues();
|
||||
return diffBuilder.differentiate(
|
||||
newData,
|
||||
addedEntriesProcessor,
|
||||
updatedEntriesProcessor,
|
||||
removedEntriesProcessor
|
||||
);
|
||||
return diffBuilder.differentiate(newData, changedEntriesProcessor);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StorageException("Error while applying " + this, e);
|
||||
@@ -391,27 +386,21 @@ public abstract class MapReduceIndex<Key, Value, Input> implements InvertedIndex
|
||||
|
||||
protected abstract void requestRebuild(@NotNull Throwable e);
|
||||
|
||||
private final RemovedKeyProcessor<Key> myRemovedKeyProcessor = new RemovedKeyProcessor<Key>() {
|
||||
private final UpdatedEntryProcessor<Key, Value> changedEntriesProcessor = new UpdatedEntryProcessor<Key, Value>() {
|
||||
@Override
|
||||
public void process(Key key, int inputId) throws StorageException {
|
||||
public void process(@NotNull UpdateKind kind, Key key, Value value, int inputId) throws StorageException {
|
||||
incrementModificationStamp();
|
||||
myStorage.removeAllValues(key, inputId);
|
||||
}
|
||||
};
|
||||
|
||||
private final KeyValueUpdateProcessor<Key, Value> myAddedKeyProcessor = new KeyValueUpdateProcessor<Key, Value>() {
|
||||
@Override
|
||||
public void process(Key key, Value value, int inputId) throws StorageException {
|
||||
incrementModificationStamp();
|
||||
myStorage.addValue(key, inputId, value);
|
||||
}
|
||||
};
|
||||
|
||||
private final KeyValueUpdateProcessor<Key, Value> myUpdatedKeyProcessor = new KeyValueUpdateProcessor<Key, Value>() {
|
||||
@Override
|
||||
public void process(Key key, Value value, int inputId) throws StorageException {
|
||||
incrementModificationStamp();
|
||||
myStorage.updateValue(key, inputId, value);
|
||||
switch (kind) {
|
||||
case ADDED:
|
||||
myStorage.addValue(key, inputId, value);
|
||||
break;
|
||||
case UPDATED:
|
||||
myStorage.updateValue(key, inputId, value);
|
||||
break;
|
||||
case REMOVED:
|
||||
myStorage.removeAllValues(key, inputId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -425,11 +414,8 @@ public abstract class MapReduceIndex<Key, Value, Input> implements InvertedIndex
|
||||
IndexId<?, ?> oldIndexId = IndexDebugProperties.DEBUG_INDEX_ID.get();
|
||||
try {
|
||||
IndexDebugProperties.DEBUG_INDEX_ID.set(myIndexId);
|
||||
boolean hasDifference = updateData.iterateChanges(
|
||||
myAddedKeyProcessor,
|
||||
myUpdatedKeyProcessor,
|
||||
myRemovedKeyProcessor
|
||||
);
|
||||
boolean hasDifference = updateData.iterateChanges(changedEntriesProcessor);
|
||||
|
||||
//TODO RC: separate lock for forwardIndex? -- it seems it is used only in updates (?), i.e. only in one place,
|
||||
// so if it is out-of-sync with inverted index it is not a big deal since nobody able to see it?
|
||||
// ...but it is important to not allow same fileId data to be applied by different threads, because
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.util.indexing.impl;
|
||||
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
|
||||
public interface RemovedKeyProcessor<Key> {
|
||||
void process(Key key, int inputId) throws StorageException;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import java.io.IOException;
|
||||
* <p>
|
||||
* The update as a whole is going to the forward index, while the changes are going to the inverted index.
|
||||
* So the {@link #updateForwardIndex()} is to update the forward index with the new data, and
|
||||
* {@link #iterateChanges(KeyValueUpdateProcessor, KeyValueUpdateProcessor, RemovedKeyProcessor)} is to stream
|
||||
* {@link #iterateChanges(UpdatedEntryProcessor)} is to stream
|
||||
* the changes against current data to apply on the inverted index.
|
||||
* <p>
|
||||
* The 2 sides are separated to allow indexes to skip forward index update, and/or to provide an optimized version
|
||||
@@ -47,14 +47,8 @@ public final class UpdateData<Key, Value> {
|
||||
//MAYBE RC: move ChangesProducer to the upper level, and make UpdateData implement ChangesProducer, so this
|
||||
// method become .forEachChange()?
|
||||
/** @return true if new data is different from current data -- which means at least one processor _was_ called */
|
||||
boolean iterateChanges(@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addedEntriesProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updatedEntriesProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removedEntriesProcessor) throws StorageException {
|
||||
return changesProducer.forEachChange(
|
||||
addedEntriesProcessor,
|
||||
updatedEntriesProcessor,
|
||||
removedEntriesProcessor
|
||||
);
|
||||
boolean iterateChanges(@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changedEntriesProcessor) throws StorageException {
|
||||
return changesProducer.forEachChange(changedEntriesProcessor);
|
||||
}
|
||||
|
||||
void updateForwardIndex() throws IOException {
|
||||
@@ -90,8 +84,6 @@ public final class UpdateData<Key, Value> {
|
||||
@ApiStatus.Internal
|
||||
@FunctionalInterface
|
||||
public interface ChangesProducer<Key, Value> {
|
||||
boolean forEachChange(@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addedEntriesProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updatedEntriesProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removedEntriesProcessor) throws StorageException;
|
||||
boolean forEachChange(@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changedEntriesProcessor) throws StorageException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.indexing.impl;
|
||||
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@FunctionalInterface
|
||||
public interface UpdatedEntryProcessor<Key, Value> {
|
||||
|
||||
enum UpdateKind {ADDED, UPDATED, REMOVED}
|
||||
|
||||
default void added(Key key, Value value, int inputId) throws StorageException {
|
||||
process(UpdateKind.ADDED, key, value, inputId);
|
||||
}
|
||||
|
||||
default void updated(Key key, Value value, int inputId) throws StorageException {
|
||||
process(UpdateKind.UPDATED, key, value, inputId);
|
||||
}
|
||||
|
||||
default void removed(Key key, int inputId) throws StorageException {
|
||||
process(UpdateKind.REMOVED, key, /*value: */ null, inputId);
|
||||
}
|
||||
|
||||
void process(@NotNull UpdateKind kind, Key key, Value value, int inputId) throws StorageException;
|
||||
}
|
||||
@@ -4,8 +4,7 @@ package com.intellij.util.indexing.impl.forward;
|
||||
import com.intellij.openapi.util.io.ByteArraySequence;
|
||||
import com.intellij.util.indexing.impl.InputData;
|
||||
import com.intellij.util.indexing.impl.InputDataDiffBuilder;
|
||||
import com.intellij.util.indexing.impl.KeyValueUpdateProcessor;
|
||||
import com.intellij.util.indexing.impl.RemovedKeyProcessor;
|
||||
import com.intellij.util.indexing.impl.UpdatedEntryProcessor;
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -19,7 +18,7 @@ public interface ForwardIndexAccessor<Key, Value> {
|
||||
* Method deserializes sequence bytes back into a {@link InputData}, and creates a diff-builder from this input
|
||||
* (with id=inputId).
|
||||
* The diff-builder could be used later to calculate a diff between that inputData, and any other inputData
|
||||
* (see {@link InputDataDiffBuilder#differentiate(Map, KeyValueUpdateProcessor, KeyValueUpdateProcessor, RemovedKeyProcessor)})
|
||||
* (see {@link InputDataDiffBuilder#differentiate(Map, UpdatedEntryProcessor)})
|
||||
*/
|
||||
@NotNull
|
||||
InputDataDiffBuilder<Key, Value> getDiffBuilder(int inputId, @Nullable ByteArraySequence sequence) throws IOException;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.indexing.impl.forward;
|
||||
|
||||
import com.intellij.util.indexing.IndexExtension;
|
||||
@@ -51,13 +51,11 @@ public final class KeyCollectionForwardIndexAccessor<Key, Value> extends Abstrac
|
||||
|
||||
@Override
|
||||
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException {
|
||||
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException {
|
||||
for (Key key : myKeys) {
|
||||
removeProcessor.process(key, myInputId);
|
||||
changesProcessor.removed(key, myInputId);
|
||||
}
|
||||
boolean anyAdded = EmptyInputDataDiffBuilder.processAllKeyValuesAsAdded(myInputId, newData, addProcessor);
|
||||
boolean anyAdded = EmptyInputDataDiffBuilder.processAllKeyValuesAsAdded(myInputId, newData, changesProcessor);
|
||||
boolean anyRemoved = !myKeys.isEmpty();
|
||||
return anyAdded || anyRemoved;
|
||||
}
|
||||
|
||||
@@ -285,14 +285,8 @@ public abstract class IndexStorageLayoutProviderTestBase {
|
||||
ByteArraySequence serializedData = forwardIndex.get(inputId);
|
||||
forwardIndexAccessor.getDiffBuilder(inputId, serializedData).differentiate(
|
||||
expectedInputData,
|
||||
(k, v, _inputId) -> {
|
||||
inconsistencies.add("add(" + k + ", " + v + ")[" + _inputId + "]");
|
||||
},
|
||||
(k, v, _inputId) -> {
|
||||
inconsistencies.add("update(" + k + ", " + v + ")[" + _inputId + "]");
|
||||
},
|
||||
(k, _inputId) -> {
|
||||
inconsistencies.add("remove(" + k + ")[" + _inputId + "]");
|
||||
(kind, k, v, _inputId) -> {
|
||||
inconsistencies.add(kind + "(" + k + ", " + v + ")[" + _inputId + "]");
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -351,16 +345,11 @@ public abstract class IndexStorageLayoutProviderTestBase {
|
||||
inputId,
|
||||
serializedData
|
||||
);
|
||||
diffBuilder.differentiate(expectedInputData,
|
||||
(k, v, _inputId) -> {
|
||||
fail();
|
||||
},
|
||||
(k, v, _inputId) -> {
|
||||
fail();
|
||||
},
|
||||
(k, _inputId) -> {
|
||||
fail();
|
||||
});
|
||||
diffBuilder.differentiate(
|
||||
expectedInputData,
|
||||
(kind, key, value, _inputId) -> {
|
||||
fail("Shouldn't be any difference, but: " + kind + "(" + key + ", " + value + ")[" + _inputId + "]");
|
||||
});
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
|
||||
Reference in New Issue
Block a user