Skip to content

Commit 07718dd

Browse files
committed
refactor: changes in index manager and view implementation to avoid cross locking during updates
1 parent dfba4cf commit 07718dd

5 files changed

Lines changed: 63 additions & 56 deletions

File tree

core/src/main/java/com/orientechnologies/orient/core/config/OGlobalConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ public enum OGlobalConfiguration { // ENVIRONMENT
850850
"Configure the TreeMaps for manual indexes as buffered or not. -1 means buffered until tx.commit() or db.close() are called",
851851
Integer.class,
852852
1),
853-
853+
@Deprecated
854854
INDEX_DURABLE_IN_NON_TX_MODE(
855855
"index.durableInNonTxMode",
856856
"Indicates whether index implementation for plocal storage will be durable in non-Tx mode (true by default)",

core/src/main/java/com/orientechnologies/orient/core/db/viewmanager/ViewManager.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ public class ViewManager {
7676
*/
7777
private final ConcurrentMap<String, AtomicInteger> viewIndexVisitors = new ConcurrentHashMap<>();
7878

79-
private final ConcurrentMap<String, String> oldIndexesPerViews = new ConcurrentHashMap<>();
8079
private final List<String> indexesToDrop = Collections.synchronizedList(new ArrayList<>());
8180

8281
private final ConcurrentMap<String, Long> lastUpdateTimestampForView = new ConcurrentHashMap<>();
@@ -226,7 +225,6 @@ public void cleanUnusedViewIndexes(ODatabaseDocumentInternal db) {
226225
for (String index : indexes) {
227226
db.getMetadata().getIndexManagerInternal().dropIndex(db, index);
228227
viewIndexVisitors.remove(index);
229-
oldIndexesPerViews.remove(index);
230228
}
231229
}
232230

@@ -390,7 +388,6 @@ public Object call() {
390388
db.getClusterNameById(cluster));
391389
for (int i : oldMetadata.getClusters()) {
392390
clustersToDrop.add(i);
393-
viewCluserVisitors.put(i, new AtomicInteger(0));
394391
oldClustersPerViews.put(i, view.getName());
395392
}
396393

@@ -399,8 +396,6 @@ public Object call() {
399396
.forEach(
400397
idx -> {
401398
indexesToDrop.add(idx);
402-
viewIndexVisitors.put(idx, new AtomicInteger(0));
403-
oldIndexesPerViews.put(idx, viewName);
404399
});
405400
cleanUnusedViewIndexes(db);
406401
cleanUnusedViewClusters(db);
@@ -482,7 +477,7 @@ private String getNextClusterNameFor(OView view, ODatabase db) {
482477
String viewName = view.getName();
483478
while (true) {
484479
String clusterName = "v_" + i++ + "_" + viewName.toLowerCase(Locale.ENGLISH);
485-
if (!db.getClusterNames().contains(clusterName)) {
480+
if (!db.existsCluster(clusterName)) {
486481
return clusterName;
487482
}
488483
}

core/src/main/java/com/orientechnologies/orient/core/index/OIndexManagerShared.java

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import java.util.Map;
5858
import java.util.Optional;
5959
import java.util.Set;
60-
import java.util.concurrent.Callable;
6160
import java.util.concurrent.ConcurrentHashMap;
6261
import java.util.concurrent.atomic.AtomicInteger;
6362
import java.util.concurrent.locks.ReadWriteLock;
@@ -126,42 +125,16 @@ public void reload() {
126125
public void save() {
127126

128127
OScenarioThreadLocal.executeAsDistributed(
129-
new Callable<Object>() {
130-
@Override
131-
public Object call() {
132-
acquireExclusiveLock();
133-
134-
try {
135-
boolean saved = false;
136-
for (int retry = 0; retry < 10; retry++)
137-
try {
138-
139-
toStream();
140-
document.save();
141-
saved = true;
142-
break;
143-
144-
} catch (OConcurrentModificationException e) {
145-
OLogManager.instance()
146-
.debug(
147-
this,
148-
"concurrent modification while saving index manager configuration",
149-
e);
150-
document.reload(null, true);
151-
}
152-
153-
if (!saved)
154-
OLogManager.instance()
155-
.error(
156-
this,
157-
"failed to save the index manager configuration after 10 retries",
158-
null);
159-
160-
return null;
161-
162-
} finally {
163-
releaseExclusiveLock();
164-
}
128+
() -> {
129+
acquireExclusiveLock();
130+
131+
try {
132+
internalSave();
133+
134+
return null;
135+
136+
} finally {
137+
releaseExclusiveLock();
165138
}
166139
});
167140
}
@@ -456,8 +429,12 @@ protected void releaseExclusiveLock(boolean save) {
456429
try {
457430
if (val == 0 && database != null) {
458431
if (save) {
459-
this.setDirty();
460-
this.save();
432+
document.setDirty();
433+
OScenarioThreadLocal.executeAsDistributed(
434+
() -> {
435+
internalSave();
436+
return null;
437+
});
461438
}
462439
}
463440
} finally {
@@ -684,9 +661,6 @@ public OIndex createIndex(
684661
// manual indexes are always durable
685662
if (clusterIdsToIndex == null || clusterIdsToIndex.length == 0) {
686663
if (metadata == null) metadata = new ODocument().setTrackingChanges(false);
687-
688-
final Object durable = metadata.field("durableInNonTxMode");
689-
if (!(durable instanceof Boolean)) metadata.field("durableInNonTxMode", true);
690664
if (metadata.field("trackMode") == null) metadata.field("trackMode", "FULL");
691665
}
692666

@@ -723,10 +697,9 @@ public OIndex createIndex(
723697

724698
} finally {
725699
releaseExclusiveLock(true);
700+
notifyInvolvedClasses(database, clusterIdsToIndex);
726701
}
727702

728-
notifyInvolvedClasses(database, clusterIdsToIndex);
729-
730703
return index;
731704
}
732705

@@ -861,11 +834,10 @@ public void dropIndex(ODatabaseDocumentInternal database, final String iIndexNam
861834

862835
idx.delete();
863836
indexes.remove(iIndexName);
864-
865-
notifyInvolvedClasses(database, clusterIdsToIndex);
866837
}
867838
} finally {
868839
releaseExclusiveLock(true);
840+
notifyInvolvedClasses(database, clusterIdsToIndex);
869841
}
870842
}
871843

@@ -1102,4 +1074,25 @@ protected OStorage getStorage() {
11021074
public ODocument getDocument() {
11031075
return document;
11041076
}
1077+
1078+
private void internalSave() {
1079+
boolean saved = false;
1080+
for (int retry = 0; retry < 10; retry++)
1081+
try {
1082+
1083+
toStream();
1084+
document.save();
1085+
saved = true;
1086+
break;
1087+
1088+
} catch (OConcurrentModificationException e) {
1089+
OLogManager.instance()
1090+
.debug(this, "concurrent modification while saving index manager configuration", e);
1091+
document.reload(null, true);
1092+
}
1093+
1094+
if (!saved)
1095+
OLogManager.instance()
1096+
.error(this, "failed to save the index manager configuration after 10 retries", null);
1097+
}
11051098
}

core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OClassImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,25 @@ protected void removePolymorphicClusterIds(final OClassImpl iBaseClass) {
16531653
removePolymorphicClusterId(clusterId);
16541654
}
16551655

1656+
protected void onlyRemovePolymorphicClusterId(final int clusterId) {
1657+
final int index = Arrays.binarySearch(polymorphicClusterIds, clusterId);
1658+
if (index < 0) return;
1659+
1660+
if (index < polymorphicClusterIds.length - 1)
1661+
System.arraycopy(
1662+
polymorphicClusterIds,
1663+
index + 1,
1664+
polymorphicClusterIds,
1665+
index,
1666+
polymorphicClusterIds.length - (index + 1));
1667+
1668+
polymorphicClusterIds = Arrays.copyOf(polymorphicClusterIds, polymorphicClusterIds.length - 1);
1669+
1670+
for (OClassImpl superClass : superClasses) {
1671+
superClass.onlyRemovePolymorphicClusterId(clusterId);
1672+
}
1673+
}
1674+
16561675
protected void removePolymorphicClusterId(final int clusterId) {
16571676
final int index = Arrays.binarySearch(polymorphicClusterIds, clusterId);
16581677
if (index < 0) return;

core/src/main/java/com/orientechnologies/orient/core/metadata/schema/OViewEmbedded.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ private OClass removeClusterIdInternal(
237237
}
238238
clusterIds = newClusterIds;
239239

240-
removePolymorphicClusterId(clusterToRemove);
240+
onlyRemovePolymorphicClusterId(clusterToRemove);
241241
}
242242

243243
if (defaultClusterId == clusterToRemove) {
@@ -274,13 +274,13 @@ public OClass setAbstract(boolean isAbstract) {
274274
public OViewRemovedMetadata replaceViewClusterAndIndex(final int cluster, List<OIndex> indexes) {
275275
acquireSchemaWriteLock();
276276
try {
277+
List<String> oldIndexes = getInactiveIndexes();
278+
inactivateIndexes();
277279
int[] oldClusters = getClusterIds();
278280
addClusterId(cluster);
279281
for (int i : oldClusters) {
280282
removeClusterId(i);
281283
}
282-
List<String> oldIndexes = getInactiveIndexes();
283-
inactivateIndexes();
284284
addActiveIndexes(indexes.stream().map(x -> x.getName()).collect(Collectors.toList()));
285285
return new OViewRemovedMetadata(oldClusters, oldIndexes);
286286
} finally {

0 commit comments

Comments
 (0)