mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +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;
|
package com.intellij.psi.stubs;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
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.StorageException;
|
||||||
import com.intellij.util.indexing.impl.DirectInputDataDiffBuilder;
|
import com.intellij.util.indexing.impl.DirectInputDataDiffBuilder;
|
||||||
import com.intellij.util.indexing.impl.IndexDebugProperties;
|
import com.intellij.util.indexing.impl.IndexDebugProperties;
|
||||||
import com.intellij.util.indexing.impl.KeyValueUpdateProcessor;
|
import com.intellij.util.indexing.impl.UpdatedEntryProcessor;
|
||||||
import com.intellij.util.indexing.impl.RemovedKeyProcessor;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -28,20 +27,15 @@ final class StubCumulativeInputDiffBuilder extends DirectInputDataDiffBuilder<In
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean differentiate(@NotNull Map<Integer, SerializedStubTree> newData,
|
public boolean differentiate(@NotNull Map<Integer, SerializedStubTree> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Integer, ? super SerializedStubTree> changesProcessor) throws StorageException {
|
||||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> updateProcessor,
|
return differentiate(newData, changesProcessor, false);
|
||||||
@NotNull RemovedKeyProcessor<? super Integer> removeProcessor) throws StorageException
|
|
||||||
{
|
|
||||||
return differentiate(newData, addProcessor, updateProcessor, removeProcessor, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dryRun if true, won't update the stub indices
|
* @param dryRun if true, won't update the stub indices
|
||||||
*/
|
*/
|
||||||
public boolean differentiate(@NotNull Map<Integer, SerializedStubTree> newData,
|
public boolean differentiate(@NotNull Map<Integer, SerializedStubTree> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Integer, ? super SerializedStubTree> changesProcessor,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super SerializedStubTree> updateProcessor,
|
|
||||||
@NotNull RemovedKeyProcessor<? super Integer> removeProcessor,
|
|
||||||
boolean dryRun) throws StorageException {
|
boolean dryRun) throws StorageException {
|
||||||
if (FileBasedIndexEx.TRACE_STUB_INDEX_UPDATES) {
|
if (FileBasedIndexEx.TRACE_STUB_INDEX_UPDATES) {
|
||||||
LOG.info((dryRun ? "[dry run]" : "") + "differentiate: inputId=" + myInputId +
|
LOG.info((dryRun ? "[dry run]" : "") + "differentiate: inputId=" + myInputId +
|
||||||
@@ -69,9 +63,9 @@ final class StubCumulativeInputDiffBuilder extends DirectInputDataDiffBuilder<In
|
|||||||
",newStubLen=" + newSerializedStubTree.myIndexedStubByteLength);
|
",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);
|
if (!dryRun) updateStubIndices(newSerializedStubTree);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -81,7 +75,7 @@ final class StubCumulativeInputDiffBuilder extends DirectInputDataDiffBuilder<In
|
|||||||
}
|
}
|
||||||
return false; // ?????????
|
return false; // ?????????
|
||||||
}
|
}
|
||||||
removeProcessor.process(myInputId, myInputId);
|
changesProcessor.removed(myInputId, myInputId);
|
||||||
if (!dryRun) updateStubIndices(null);
|
if (!dryRun) updateStubIndices(null);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -92,19 +92,19 @@ public abstract class StubIndexEx extends StubIndex {
|
|||||||
fileId,
|
fileId,
|
||||||
index.getExtension().getName(),
|
index.getExtension().getName(),
|
||||||
|
|
||||||
(addedEntriesProcessor, updatedEntriesProcessor, removedEntriesProcessor) -> {
|
(changedEntriesProcessor) -> {
|
||||||
|
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
for (K oldKey : oldKeys) {
|
for (K oldKey : oldKeys) {
|
||||||
if (!newKeys.contains(oldKey)) {
|
if (!newKeys.contains(oldKey)) {
|
||||||
removedEntriesProcessor.process(oldKey, fileId);
|
changedEntriesProcessor.removed(oldKey, fileId);
|
||||||
if (!modified) modified = true;
|
if (!modified) modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (K newKey : newKeys) {
|
for (K newKey : newKeys) {
|
||||||
if (!oldKeys.contains(newKey)) {
|
if (!oldKeys.contains(newKey)) {
|
||||||
addedEntriesProcessor.process(newKey, null, fileId);
|
changedEntriesProcessor.added(newKey, null, fileId);
|
||||||
if (!modified) modified = true;
|
if (!modified) modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,27 +99,25 @@ public class SingleEntryIndexForwardIndexAccessor<V> extends AbstractMapForwardI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean differentiate(@NotNull Map<Integer, V> newData,
|
public boolean differentiate(@NotNull Map<Integer, V> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super V> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Integer, ? super V> changesProcessor) throws StorageException {
|
||||||
@NotNull KeyValueUpdateProcessor<? super Integer, ? super V> updateProcessor,
|
|
||||||
@NotNull RemovedKeyProcessor<? super Integer> removeProcessor) throws StorageException {
|
|
||||||
boolean newValueExists = !newData.isEmpty();
|
boolean newValueExists = !newData.isEmpty();
|
||||||
V newValue = ContainerUtil.getFirstItem(newData.values());
|
V newValue = ContainerUtil.getFirstItem(newData.values());
|
||||||
if (myContainsValue) {
|
if (myContainsValue) {
|
||||||
if (!newValueExists) {
|
if (!newValueExists) {
|
||||||
removeProcessor.process(myInputId, myInputId);
|
changesProcessor.removed(myInputId, myInputId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (Comparing.equal(myCurrentValue, newValue)) {
|
else if (Comparing.equal(myCurrentValue, newValue)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
updateProcessor.process(myInputId, newValue, myInputId);
|
changesProcessor.updated(myInputId, newValue, myInputId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (newValueExists) {
|
if (newValueExists) {
|
||||||
addProcessor.process(myInputId, newValue, myInputId);
|
changesProcessor.added(myInputId, newValue, myInputId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ final class PerFileElementTypeStubModificationTracker implements StubIndexImpl.F
|
|||||||
}
|
}
|
||||||
final Stub stub = StubTreeBuilder.buildStubTree(fileContent);
|
final Stub stub = StubTreeBuilder.buildStubTree(fileContent);
|
||||||
Map<Integer, SerializedStubTree> serializedStub = stub == null ? Collections.emptyMap() : stubIndexer.map(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);
|
registerModificationFor(info.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4306,12 +4306,6 @@ f:com.intellij.util.indexing.impl.CollectionDataExternalizer
|
|||||||
- <init>(com.intellij.util.io.DataExternalizer):V
|
- <init>(com.intellij.util.io.DataExternalizer):V
|
||||||
- read(java.io.DataInput):java.util.Collection
|
- read(java.io.DataInput):java.util.Collection
|
||||||
- save(java.io.DataOutput,java.util.Collection):V
|
- 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
|
com.intellij.util.indexing.impl.IndexStorage
|
||||||
- java.io.Closeable
|
- java.io.Closeable
|
||||||
- java.io.Flushable
|
- 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
|
- <init>(com.intellij.util.io.KeyDescriptor,com.intellij.util.indexing.IndexId):V
|
||||||
- read(java.io.DataInput):java.util.Collection
|
- read(java.io.DataInput):java.util.Collection
|
||||||
- save(java.io.DataOutput,java.util.Collection):V
|
- 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
|
*f:com.intellij.util.indexing.impl.MapReduceIndexMappingException
|
||||||
- java.lang.RuntimeException
|
- java.lang.RuntimeException
|
||||||
- <init>(java.lang.Throwable,java.lang.Class):V
|
- <init>(java.lang.Throwable,java.lang.Class):V
|
||||||
- getClassToBlame():java.lang.Class
|
- getClassToBlame():java.lang.Class
|
||||||
com.intellij.util.indexing.impl.RemovedKeyProcessor
|
|
||||||
- a:process(java.lang.Object,I):V
|
|
||||||
com.intellij.util.indexing.impl.ValueSerializationProblemReporter
|
com.intellij.util.indexing.impl.ValueSerializationProblemReporter
|
||||||
- a:reportProblem(java.lang.Exception):V
|
- a:reportProblem(java.lang.Exception):V
|
||||||
com.intellij.util.indexing.impl.forward.ForwardIndex
|
com.intellij.util.indexing.impl.forward.ForwardIndex
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
package com.intellij.util.indexing.impl;
|
package com.intellij.util.indexing.impl;
|
||||||
|
|
||||||
import com.intellij.util.indexing.StorageException;
|
import com.intellij.util.indexing.StorageException;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
public final class EmptyInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuilder<Key, Value> {
|
public final class EmptyInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuilder<Key, Value> {
|
||||||
public EmptyInputDataDiffBuilder(int inputId) {
|
public EmptyInputDataDiffBuilder(int inputId) {
|
||||||
super(inputId);
|
super(inputId);
|
||||||
@@ -20,21 +22,19 @@ public final class EmptyInputDataDiffBuilder<Key, Value> extends DirectInputData
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException {
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
return processAllKeyValuesAsAdded(myInputId, newData, changesProcessor);
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException {
|
|
||||||
return processAllKeyValuesAsAdded(myInputId, newData, addProcessor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <Key, Value> boolean processAllKeyValuesAsAdded(int inputId,
|
public static <Key, Value> boolean processAllKeyValuesAsAdded(int inputId,
|
||||||
@NotNull Map<Key, Value> addedData,
|
@NotNull Map<Key, Value> addedData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor)
|
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor)
|
||||||
throws StorageException {
|
throws StorageException {
|
||||||
boolean[] anyAdded = {false};
|
boolean[] anyAdded = {false};
|
||||||
try {
|
try {
|
||||||
addedData.forEach((key, value) -> {
|
addedData.forEach((key, value) -> {
|
||||||
try {
|
try {
|
||||||
addProcessor.process(key, value, inputId);
|
changesProcessor.added(key, value, inputId);
|
||||||
}
|
}
|
||||||
catch (StorageException e) {
|
catch (StorageException e) {
|
||||||
throw new RuntimeException(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,
|
public static <Key, Value> boolean processAllKeyValuesAsRemoved(int inputId,
|
||||||
@NotNull Map<Key, Value> removedData,
|
@NotNull Map<Key, Value> removedData,
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removedProcessor) throws StorageException {
|
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor)
|
||||||
|
throws StorageException {
|
||||||
boolean anyRemoved = false;
|
boolean anyRemoved = false;
|
||||||
for (Key key : removedData.keySet()) {
|
for (Key key : removedData.keySet()) {
|
||||||
removedProcessor.process(key, inputId);
|
changesProcessor.removed(key, inputId);
|
||||||
anyRemoved = true;
|
anyRemoved = true;
|
||||||
}
|
}
|
||||||
return anyRemoved;
|
return anyRemoved;
|
||||||
|
|||||||
@@ -1,18 +1,4 @@
|
|||||||
/*
|
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||||
* 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;
|
package com.intellij.util.indexing.impl;
|
||||||
|
|
||||||
import com.intellij.util.indexing.StorageException;
|
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
|
* @return false if there is no difference and true otherwise
|
||||||
*/
|
*/
|
||||||
public abstract boolean differentiate(@NotNull Map<Key, Value> newData,
|
public abstract boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException;
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) 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;
|
package com.intellij.util.indexing.impl;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.util.Comparing;
|
import com.intellij.openapi.util.Comparing;
|
||||||
import com.intellij.util.indexing.StorageException;
|
import com.intellij.util.indexing.StorageException;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuilder<Key, Value> {
|
public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuilder<Key, Value> {
|
||||||
private final @NotNull Map<Key, Value> myMap;
|
private final @NotNull Map<Key, Value> myMap;
|
||||||
|
|
||||||
@@ -22,14 +24,12 @@ public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuil
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException {
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException {
|
|
||||||
if (myMap.isEmpty()) {
|
if (myMap.isEmpty()) {
|
||||||
return EmptyInputDataDiffBuilder.processAllKeyValuesAsAdded(myInputId, newData, addProcessor);
|
return EmptyInputDataDiffBuilder.processAllKeyValuesAsAdded(myInputId, newData, changesProcessor);
|
||||||
}
|
}
|
||||||
if (newData.isEmpty()) {
|
if (newData.isEmpty()) {
|
||||||
return EmptyInputDataDiffBuilder.processAllKeyValuesAsRemoved(myInputId, myMap, removeProcessor);
|
return EmptyInputDataDiffBuilder.processAllKeyValuesAsRemoved(myInputId, myMap, changesProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
int added = 0;
|
int added = 0;
|
||||||
@@ -42,11 +42,11 @@ public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuil
|
|||||||
Value newValue = newData.get(key);
|
Value newValue = newData.get(key);
|
||||||
if (!Comparing.equal(oldValue, newValue) || (newValue == null && !newData.containsKey(key))) {
|
if (!Comparing.equal(oldValue, newValue) || (newValue == null && !newData.containsKey(key))) {
|
||||||
if (newData.containsKey(key)) {
|
if (newData.containsKey(key)) {
|
||||||
updateProcessor.process(key, newValue, myInputId);
|
changesProcessor.updated(key, newValue, myInputId);
|
||||||
updated++;
|
updated++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
removeProcessor.process(key, myInputId);
|
changesProcessor.removed(key, myInputId);
|
||||||
removed++;
|
removed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ public class MapInputDataDiffBuilder<Key, Value> extends DirectInputDataDiffBuil
|
|||||||
for (Map.Entry<Key, Value> e : newData.entrySet()) {
|
for (Map.Entry<Key, Value> e : newData.entrySet()) {
|
||||||
final Key newKey = e.getKey();
|
final Key newKey = e.getKey();
|
||||||
if (!myMap.containsKey(newKey)) {
|
if (!myMap.containsKey(newKey)) {
|
||||||
addProcessor.process(newKey, e.getValue(), myInputId);
|
changesProcessor.added(newKey, e.getValue(), myInputId);
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,16 +313,11 @@ public abstract class MapReduceIndex<Key, Value, Input> implements InvertedIndex
|
|||||||
inputId,
|
inputId,
|
||||||
indexId(),
|
indexId(),
|
||||||
|
|
||||||
(addedEntriesProcessor, updatedEntriesProcessor, removedEntriesProcessor) -> {
|
(changedEntriesProcessor) -> {
|
||||||
try {
|
try {
|
||||||
InputDataDiffBuilder<Key, Value> diffBuilder = getKeysDiffBuilder(inputId);
|
InputDataDiffBuilder<Key, Value> diffBuilder = getKeysDiffBuilder(inputId);
|
||||||
Map<Key, Value> newData = inputData.getKeyValues();
|
Map<Key, Value> newData = inputData.getKeyValues();
|
||||||
return diffBuilder.differentiate(
|
return diffBuilder.differentiate(newData, changedEntriesProcessor);
|
||||||
newData,
|
|
||||||
addedEntriesProcessor,
|
|
||||||
updatedEntriesProcessor,
|
|
||||||
removedEntriesProcessor
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new StorageException("Error while applying " + this, 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);
|
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
|
@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();
|
incrementModificationStamp();
|
||||||
myStorage.removeAllValues(key, inputId);
|
switch (kind) {
|
||||||
}
|
case ADDED:
|
||||||
};
|
myStorage.addValue(key, inputId, value);
|
||||||
|
break;
|
||||||
private final KeyValueUpdateProcessor<Key, Value> myAddedKeyProcessor = new KeyValueUpdateProcessor<Key, Value>() {
|
case UPDATED:
|
||||||
@Override
|
myStorage.updateValue(key, inputId, value);
|
||||||
public void process(Key key, Value value, int inputId) throws StorageException {
|
break;
|
||||||
incrementModificationStamp();
|
case REMOVED:
|
||||||
myStorage.addValue(key, inputId, value);
|
myStorage.removeAllValues(key, inputId);
|
||||||
}
|
break;
|
||||||
};
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -425,11 +414,8 @@ public abstract class MapReduceIndex<Key, Value, Input> implements InvertedIndex
|
|||||||
IndexId<?, ?> oldIndexId = IndexDebugProperties.DEBUG_INDEX_ID.get();
|
IndexId<?, ?> oldIndexId = IndexDebugProperties.DEBUG_INDEX_ID.get();
|
||||||
try {
|
try {
|
||||||
IndexDebugProperties.DEBUG_INDEX_ID.set(myIndexId);
|
IndexDebugProperties.DEBUG_INDEX_ID.set(myIndexId);
|
||||||
boolean hasDifference = updateData.iterateChanges(
|
boolean hasDifference = updateData.iterateChanges(changedEntriesProcessor);
|
||||||
myAddedKeyProcessor,
|
|
||||||
myUpdatedKeyProcessor,
|
|
||||||
myRemovedKeyProcessor
|
|
||||||
);
|
|
||||||
//TODO RC: separate lock for forwardIndex? -- it seems it is used only in updates (?), i.e. only in one place,
|
//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?
|
// 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
|
// ...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>
|
* <p>
|
||||||
* The update as a whole is going to the forward index, while the changes are going to the inverted index.
|
* 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
|
* 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.
|
* the changes against current data to apply on the inverted index.
|
||||||
* <p>
|
* <p>
|
||||||
* The 2 sides are separated to allow indexes to skip forward index update, and/or to provide an optimized version
|
* 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
|
//MAYBE RC: move ChangesProducer to the upper level, and make UpdateData implement ChangesProducer, so this
|
||||||
// method become .forEachChange()?
|
// method become .forEachChange()?
|
||||||
/** @return true if new data is different from current data -- which means at least one processor _was_ called */
|
/** @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,
|
boolean iterateChanges(@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changedEntriesProcessor) throws StorageException {
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updatedEntriesProcessor,
|
return changesProducer.forEachChange(changedEntriesProcessor);
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removedEntriesProcessor) throws StorageException {
|
|
||||||
return changesProducer.forEachChange(
|
|
||||||
addedEntriesProcessor,
|
|
||||||
updatedEntriesProcessor,
|
|
||||||
removedEntriesProcessor
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateForwardIndex() throws IOException {
|
void updateForwardIndex() throws IOException {
|
||||||
@@ -90,8 +84,6 @@ public final class UpdateData<Key, Value> {
|
|||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ChangesProducer<Key, Value> {
|
public interface ChangesProducer<Key, Value> {
|
||||||
boolean forEachChange(@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addedEntriesProcessor,
|
boolean forEachChange(@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changedEntriesProcessor) throws StorageException;
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updatedEntriesProcessor,
|
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removedEntriesProcessor) 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.openapi.util.io.ByteArraySequence;
|
||||||
import com.intellij.util.indexing.impl.InputData;
|
import com.intellij.util.indexing.impl.InputData;
|
||||||
import com.intellij.util.indexing.impl.InputDataDiffBuilder;
|
import com.intellij.util.indexing.impl.InputDataDiffBuilder;
|
||||||
import com.intellij.util.indexing.impl.KeyValueUpdateProcessor;
|
import com.intellij.util.indexing.impl.UpdatedEntryProcessor;
|
||||||
import com.intellij.util.indexing.impl.RemovedKeyProcessor;
|
|
||||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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
|
* Method deserializes sequence bytes back into a {@link InputData}, and creates a diff-builder from this input
|
||||||
* (with id=inputId).
|
* (with id=inputId).
|
||||||
* The diff-builder could be used later to calculate a diff between that inputData, and any other inputData
|
* 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
|
@NotNull
|
||||||
InputDataDiffBuilder<Key, Value> getDiffBuilder(int inputId, @Nullable ByteArraySequence sequence) throws IOException;
|
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;
|
package com.intellij.util.indexing.impl.forward;
|
||||||
|
|
||||||
import com.intellij.util.indexing.IndexExtension;
|
import com.intellij.util.indexing.IndexExtension;
|
||||||
@@ -51,13 +51,11 @@ public final class KeyCollectionForwardIndexAccessor<Key, Value> extends Abstrac
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
public boolean differentiate(@NotNull Map<Key, Value> newData,
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> addProcessor,
|
@NotNull UpdatedEntryProcessor<? super Key, ? super Value> changesProcessor) throws StorageException {
|
||||||
@NotNull KeyValueUpdateProcessor<? super Key, ? super Value> updateProcessor,
|
|
||||||
@NotNull RemovedKeyProcessor<? super Key> removeProcessor) throws StorageException {
|
|
||||||
for (Key key : myKeys) {
|
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();
|
boolean anyRemoved = !myKeys.isEmpty();
|
||||||
return anyAdded || anyRemoved;
|
return anyAdded || anyRemoved;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,14 +285,8 @@ public abstract class IndexStorageLayoutProviderTestBase {
|
|||||||
ByteArraySequence serializedData = forwardIndex.get(inputId);
|
ByteArraySequence serializedData = forwardIndex.get(inputId);
|
||||||
forwardIndexAccessor.getDiffBuilder(inputId, serializedData).differentiate(
|
forwardIndexAccessor.getDiffBuilder(inputId, serializedData).differentiate(
|
||||||
expectedInputData,
|
expectedInputData,
|
||||||
(k, v, _inputId) -> {
|
(kind, k, v, _inputId) -> {
|
||||||
inconsistencies.add("add(" + k + ", " + v + ")[" + _inputId + "]");
|
inconsistencies.add(kind + "(" + k + ", " + v + ")[" + _inputId + "]");
|
||||||
},
|
|
||||||
(k, v, _inputId) -> {
|
|
||||||
inconsistencies.add("update(" + k + ", " + v + ")[" + _inputId + "]");
|
|
||||||
},
|
|
||||||
(k, _inputId) -> {
|
|
||||||
inconsistencies.add("remove(" + k + ")[" + _inputId + "]");
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -351,16 +345,11 @@ public abstract class IndexStorageLayoutProviderTestBase {
|
|||||||
inputId,
|
inputId,
|
||||||
serializedData
|
serializedData
|
||||||
);
|
);
|
||||||
diffBuilder.differentiate(expectedInputData,
|
diffBuilder.differentiate(
|
||||||
(k, v, _inputId) -> {
|
expectedInputData,
|
||||||
fail();
|
(kind, key, value, _inputId) -> {
|
||||||
},
|
fail("Shouldn't be any difference, but: " + kind + "(" + key + ", " + value + ")[" + _inputId + "]");
|
||||||
(k, v, _inputId) -> {
|
});
|
||||||
fail();
|
|
||||||
},
|
|
||||||
(k, _inputId) -> {
|
|
||||||
fail();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
|
|||||||
Reference in New Issue
Block a user