
=== modified file 'src/com/goldencode/p2j/persist/FastFindCache.java'
--- old/src/com/goldencode/p2j/persist/FastFindCache.java	2023-01-20 12:07:41 +0000
+++ new/src/com/goldencode/p2j/persist/FastFindCache.java	2023-02-23 21:24:53 +0000
@@ -79,6 +79,7 @@
 import java.lang.ref.*;
 import java.util.*;
 import java.util.BitSet;
+import java.util.concurrent.*;
 
 /**
  * Implementation of FastFind caching algorithm. The internal structures use a triple-cache to store the
@@ -113,7 +114,7 @@
    public static final RecordIdentifier<String> NO_RECORD = new RecordIdentifier<>("", -1L);
    
    /** The singleton instance for permanent database(s). */
-   private static final FastFindCache permanentInstance = new FastFindCache();
+   private static final Map<String, FastFindCache> permanentInstances = new ConcurrentHashMap<>();
    
    /** The context-local instance for the current session for temp-tables. */
    private static final ContextLocal<FastFindCache> tempTableInstances = new ContextLocal<FastFindCache>()
@@ -121,7 +122,7 @@
       @Override
       protected FastFindCache initialValue()
       {
-         return new FastFindCache();
+         return new FastFindCache(false);
       }
    };
    
@@ -130,7 +131,14 @@
    
    /** Reverse cache of record identifiers to invalidation info, for queries with non-indexed properties */
    private final ReverseLookup reverseLookup = new ReverseLookup();
-   
+
+   private final boolean isPermanent;
+
+   private FastFindCache(boolean isPermanent)
+   {
+      this.isPermanent = isPermanent;
+   }
+
    /**
     * Obtain the singleton instance, if FastFind mode enabled. 
     * Return {@code null} to disable FastFind mode.
@@ -141,9 +149,9 @@
     * 
     * @return  the static instance of {@code FastFindCache}, or {@code null} if FastFind mode is disabled.
     */
-   public static FastFindCache getInstance(boolean temporary)
+   public static FastFindCache getInstance(boolean temporary, String databaseName)
    {
-      return temporary ? tempTableInstances.get() : permanentInstance;
+      return temporary ? tempTableInstances.get() : permanentInstances.computeIfAbsent(databaseName, dbName -> new FastFindCache(true));
    }
    
    /**
@@ -428,14 +436,14 @@
     */
    private void synchronize(Runnable code)
    {
-      if (this != permanentInstance)
+      if (!isPermanent)
       {
          // no synchronization needed here
          code.run();
          return;
       }
       
-      synchronized (permanentInstance)
+      synchronized (this)
       {
          code.run();
       }

=== modified file 'src/com/goldencode/p2j/persist/Persistence.java'
--- old/src/com/goldencode/p2j/persist/Persistence.java	2023-01-20 12:07:41 +0000
+++ new/src/com/goldencode/p2j/persist/Persistence.java	2023-02-23 21:28:05 +0000
@@ -4119,7 +4119,7 @@
     * Special care is taken to not close a database session while other
     * entities are dependent upon it for services.
     */
-   class Context
+   public class Context
    {
       /** Cache of FQL strings, with or without max results and start offsets, to queries. */
       private final ExpiryCache<QueryKey, Query> staticQueryCache = new LRUCache<>(1000);
@@ -4128,7 +4128,7 @@
       private final BufferManager bufferManager = BufferManager.get();
       
       /** Object which manages newly created records */
-      private final RecordNursery nursery = new RecordNursery(FastFindCache.getInstance(isTemporary()));
+      private final RecordNursery nursery = new RecordNursery(FastFindCache.getInstance(isTemporary(), database.getName()));
       
       /** Context-local record lock context */
       private final RecordLockContext lockContext = RecordLockContext.get(Persistence.this, bufferManager);
@@ -4187,7 +4187,7 @@
        * 
        * @return  Persistence object.
        */
-      Persistence getPersistence()
+      public Persistence getPersistence()
       {
          return Persistence.this;
       }

=== modified file 'src/com/goldencode/p2j/persist/RandomAccessQuery.java'
--- old/src/com/goldencode/p2j/persist/RandomAccessQuery.java	2022-11-30 14:33:29 +0000
+++ new/src/com/goldencode/p2j/persist/RandomAccessQuery.java	2023-02-23 21:24:53 +0000
@@ -1364,7 +1364,7 @@
       
       if (!dmoMeta.isMeta() && index != 0)
       {
-         this.ffCache = FastFindCache.getInstance(buffer.isTemporary());
+         this.ffCache = FastFindCache.getInstance(buffer.isTemporary(), buffer.persistenceContext.getPersistence().getDatabase().getName());
       }
       
       // override lock type if this is a temporary buffer;  this allows some downstream optimizations

=== modified file 'src/com/goldencode/p2j/persist/RecordBuffer.java'
--- old/src/com/goldencode/p2j/persist/RecordBuffer.java	2023-01-23 18:18:57 +0000
+++ new/src/com/goldencode/p2j/persist/RecordBuffer.java	2023-02-23 21:24:53 +0000
@@ -1568,7 +1568,7 @@
    protected boolean ignoreBeforeTracking = false;
    
    /** Current persistence context */
-   protected Persistence.Context persistenceContext = null;
+   public Persistence.Context persistenceContext = null;
    
    /** Cached hash code */
    private final int hashCode;
@@ -6847,7 +6847,7 @@
       
       metadata = dmoInfo.getRecordMeta();
       
-      ffCache = FastFindCache.getInstance(isTemporary());
+      ffCache = FastFindCache.getInstance(isTemporary(), database.getName());
       
       // Notify the connection manager that this buffer is using the backing, physical database.
       onOpenOutermostScope();

=== modified file 'src/com/goldencode/p2j/persist/orm/SavepointManager.java'
--- old/src/com/goldencode/p2j/persist/orm/SavepointManager.java	2023-01-16 20:50:19 +0000
+++ new/src/com/goldencode/p2j/persist/orm/SavepointManager.java	2023-02-23 21:24:53 +0000
@@ -908,7 +908,7 @@
             changedIsIterated = false;
          }
          
-         FastFindCache.getInstance(isTemp).invalidate(dmoSet);
+         FastFindCache.getInstance(isTemp, "TODO").invalidate(dmoSet);
       }
       
       /**

=== modified file 'src/com/goldencode/p2j/persist/orm/Validation.java'
--- old/src/com/goldencode/p2j/persist/orm/Validation.java	2023-01-10 12:10:30 +0000
+++ new/src/com/goldencode/p2j/persist/orm/Validation.java	2023-02-23 21:24:53 +0000
@@ -514,7 +514,7 @@
       // to lose the optimization than to get incorrect results in a parallel thread if it was accessing
       // the cache between save and invalidate operations
       RecordMeta recMeta = dmo._recordMeta();
-      FastFindCache ffc = FastFindCache.getInstance(recMeta.isTemporary());
+      FastFindCache ffc = FastFindCache.getInstance(recMeta.isTemporary(), buffer.persistenceContext.getPersistence().getDatabase().getName());
       boolean wasNew = dmo.checkState(NEW);
       if (wasNew)
       {
