6812-fast-find-cache.diff
new/src/com/goldencode/p2j/persist/FastFindCache.java 2023-02-23 21:24:53 +0000 | ||
---|---|---|
79 | 79 |
import java.lang.ref.*; |
80 | 80 |
import java.util.*; |
81 | 81 |
import java.util.BitSet; |
82 |
import java.util.concurrent.*; |
|
82 | 83 | |
83 | 84 |
/** |
84 | 85 |
* Implementation of FastFind caching algorithm. The internal structures use a triple-cache to store the |
... | ... | |
113 | 114 |
public static final RecordIdentifier<String> NO_RECORD = new RecordIdentifier<>("", -1L); |
114 | 115 |
|
115 | 116 |
/** The singleton instance for permanent database(s). */ |
116 |
private static final FastFindCache permanentInstance = new FastFindCache();
|
|
117 |
private static final Map<String, FastFindCache> permanentInstances = new ConcurrentHashMap<>();
|
|
117 | 118 |
|
118 | 119 |
/** The context-local instance for the current session for temp-tables. */ |
119 | 120 |
private static final ContextLocal<FastFindCache> tempTableInstances = new ContextLocal<FastFindCache>() |
... | ... | |
121 | 122 |
@Override |
122 | 123 |
protected FastFindCache initialValue() |
123 | 124 |
{ |
124 |
return new FastFindCache(); |
|
125 |
return new FastFindCache(false);
|
|
125 | 126 |
} |
126 | 127 |
}; |
127 | 128 |
|
... | ... | |
130 | 131 |
|
131 | 132 |
/** Reverse cache of record identifiers to invalidation info, for queries with non-indexed properties */ |
132 | 133 |
private final ReverseLookup reverseLookup = new ReverseLookup(); |
133 |
|
|
134 | ||
135 |
private final boolean isPermanent; |
|
136 | ||
137 |
private FastFindCache(boolean isPermanent) |
|
138 |
{ |
|
139 |
this.isPermanent = isPermanent; |
|
140 |
} |
|
141 | ||
134 | 142 |
/** |
135 | 143 |
* Obtain the singleton instance, if FastFind mode enabled. |
136 | 144 |
* Return {@code null} to disable FastFind mode. |
... | ... | |
141 | 149 |
* |
142 | 150 |
* @return the static instance of {@code FastFindCache}, or {@code null} if FastFind mode is disabled. |
143 | 151 |
*/ |
144 |
public static FastFindCache getInstance(boolean temporary) |
|
152 |
public static FastFindCache getInstance(boolean temporary, String databaseName)
|
|
145 | 153 |
{ |
146 |
return temporary ? tempTableInstances.get() : permanentInstance; |
|
154 |
return temporary ? tempTableInstances.get() : permanentInstances.computeIfAbsent(databaseName, dbName -> new FastFindCache(true));
|
|
147 | 155 |
} |
148 | 156 |
|
149 | 157 |
/** |
... | ... | |
428 | 436 |
*/ |
429 | 437 |
private void synchronize(Runnable code) |
430 | 438 |
{ |
431 |
if (this != permanentInstance)
|
|
439 |
if (!isPermanent)
|
|
432 | 440 |
{ |
433 | 441 |
// no synchronization needed here |
434 | 442 |
code.run(); |
435 | 443 |
return; |
436 | 444 |
} |
437 | 445 |
|
438 |
synchronized (permanentInstance)
|
|
446 |
synchronized (this)
|
|
439 | 447 |
{ |
440 | 448 |
code.run(); |
441 | 449 |
} |
new/src/com/goldencode/p2j/persist/Persistence.java 2023-02-23 21:28:05 +0000 | ||
---|---|---|
4119 | 4119 |
* Special care is taken to not close a database session while other |
4120 | 4120 |
* entities are dependent upon it for services. |
4121 | 4121 |
*/ |
4122 |
class Context |
|
4122 |
public class Context
|
|
4123 | 4123 |
{ |
4124 | 4124 |
/** Cache of FQL strings, with or without max results and start offsets, to queries. */ |
4125 | 4125 |
private final ExpiryCache<QueryKey, Query> staticQueryCache = new LRUCache<>(1000); |
... | ... | |
4128 | 4128 |
private final BufferManager bufferManager = BufferManager.get(); |
4129 | 4129 |
|
4130 | 4130 |
/** Object which manages newly created records */ |
4131 |
private final RecordNursery nursery = new RecordNursery(FastFindCache.getInstance(isTemporary())); |
|
4131 |
private final RecordNursery nursery = new RecordNursery(FastFindCache.getInstance(isTemporary(), database.getName()));
|
|
4132 | 4132 |
|
4133 | 4133 |
/** Context-local record lock context */ |
4134 | 4134 |
private final RecordLockContext lockContext = RecordLockContext.get(Persistence.this, bufferManager); |
... | ... | |
4187 | 4187 |
* |
4188 | 4188 |
* @return Persistence object. |
4189 | 4189 |
*/ |
4190 |
Persistence getPersistence() |
|
4190 |
public Persistence getPersistence()
|
|
4191 | 4191 |
{ |
4192 | 4192 |
return Persistence.this; |
4193 | 4193 |
} |
new/src/com/goldencode/p2j/persist/RandomAccessQuery.java 2023-02-23 21:24:53 +0000 | ||
---|---|---|
1364 | 1364 |
|
1365 | 1365 |
if (!dmoMeta.isMeta() && index != 0) |
1366 | 1366 |
{ |
1367 |
this.ffCache = FastFindCache.getInstance(buffer.isTemporary()); |
|
1367 |
this.ffCache = FastFindCache.getInstance(buffer.isTemporary(), buffer.persistenceContext.getPersistence().getDatabase().getName());
|
|
1368 | 1368 |
} |
1369 | 1369 |
|
1370 | 1370 |
// override lock type if this is a temporary buffer; this allows some downstream optimizations |
new/src/com/goldencode/p2j/persist/RecordBuffer.java 2023-02-23 21:24:53 +0000 | ||
---|---|---|
1568 | 1568 |
protected boolean ignoreBeforeTracking = false; |
1569 | 1569 |
|
1570 | 1570 |
/** Current persistence context */ |
1571 |
protected Persistence.Context persistenceContext = null;
|
|
1571 |
public Persistence.Context persistenceContext = null;
|
|
1572 | 1572 |
|
1573 | 1573 |
/** Cached hash code */ |
1574 | 1574 |
private final int hashCode; |
... | ... | |
6847 | 6847 |
|
6848 | 6848 |
metadata = dmoInfo.getRecordMeta(); |
6849 | 6849 |
|
6850 |
ffCache = FastFindCache.getInstance(isTemporary()); |
|
6850 |
ffCache = FastFindCache.getInstance(isTemporary(), database.getName());
|
|
6851 | 6851 |
|
6852 | 6852 |
// Notify the connection manager that this buffer is using the backing, physical database. |
6853 | 6853 |
onOpenOutermostScope(); |
new/src/com/goldencode/p2j/persist/orm/SavepointManager.java 2023-02-23 21:24:53 +0000 | ||
---|---|---|
908 | 908 |
changedIsIterated = false; |
909 | 909 |
} |
910 | 910 |
|
911 |
FastFindCache.getInstance(isTemp).invalidate(dmoSet); |
|
911 |
FastFindCache.getInstance(isTemp, "TODO").invalidate(dmoSet);
|
|
912 | 912 |
} |
913 | 913 |
|
914 | 914 |
/** |
new/src/com/goldencode/p2j/persist/orm/Validation.java 2023-02-23 21:24:53 +0000 | ||
---|---|---|
514 | 514 |
// to lose the optimization than to get incorrect results in a parallel thread if it was accessing |
515 | 515 |
// the cache between save and invalidate operations |
516 | 516 |
RecordMeta recMeta = dmo._recordMeta(); |
517 |
FastFindCache ffc = FastFindCache.getInstance(recMeta.isTemporary()); |
|
517 |
FastFindCache ffc = FastFindCache.getInstance(recMeta.isTemporary(), buffer.persistenceContext.getPersistence().getDatabase().getName());
|
|
518 | 518 |
boolean wasNew = dmo.checkState(NEW); |
519 | 519 |
if (wasNew) |
520 | 520 |
{ |