ozeigermann    2004/02/20 03:13:23

  Modified:    src/share/org/apache/slide/util TxLRUObjectCache.java
               src/share/org/apache/slide/store ExtendedStore.java
  Log:
  Added new local cache mode that allows to use 

  databases isolation and clustering.

  

  The trick is to skip global inter-tx caching completely and only rely on

  intra-tx caching. This means every resource accessed is retrieved from

  the database and only repeated requests inside a transaction will be

  cached. This allows for the database to apply whatever isolation it has.

  

  Additionally, it allows for clustered solutions as caches are only help for 

  the duration of a transaction. 

  Global entries that may get invalid when another cluster node updates 

  them do not exist, so they are no problem.

  
  Revision  Changes    Path
  1.3       +52 -39    
jakarta-slide/src/share/org/apache/slide/util/TxLRUObjectCache.java
  
  Index: TxLRUObjectCache.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/share/org/apache/slide/util/TxLRUObjectCache.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TxLRUObjectCache.java     11 Feb 2004 11:30:20 -0000      1.2
  +++ TxLRUObjectCache.java     20 Feb 2004 11:13:23 -0000      1.3
  @@ -54,7 +54,7 @@
    */
   public class TxLRUObjectCache {
   
  -    protected Map globalCache;
  +    protected Map globalCache = null;
   
       protected Map txChangeCaches;
       protected Map txDeleteCaches;
  @@ -68,14 +68,19 @@
       protected final boolean loggingEnabled;
   
       /**
  -     * Creates a new object cache.
  +     * Creates a new object cache. If global caching is disabled, the cache
  +     * reflects isolation of underlying store as only double reads inside a single 
transaction
  +     * will be cached. This may even increase isolation as repeatable read is 
guaranteed.  
        * 
  -     * @param globalCacheSize maximum size in objects of global cache
  +     * @param globalCacheSize maximum size in objects of global cache or 
<code>-1</code> to indicate no
  +     * global cache shall be used
        * @param name the name used to construct logging category / channel
        * @param logger Slide logger to be used for logging 
        */
       public TxLRUObjectCache(int globalCacheSize, String name, Logger logger) {
  -        globalCache = new LRUMap(globalCacheSize);
  +        if (globalCacheSize != -1) {
  +            globalCache = new LRUMap(globalCacheSize);
  +        }
           txChangeCaches = new HashMap();
           txDeleteCaches = new HashMap();
   
  @@ -96,7 +101,7 @@
       }
   
       public synchronized void clear() {
  -        globalCache.clear();
  +        if (globalCache != null) globalCache.clear();
           txChangeCaches.clear();
           txDeleteCaches.clear();
       }
  @@ -118,7 +123,9 @@
                   return changed;
               }
           }
  -
  +        
  +        if (globalCache == null) return null;
  +        
           // as fall back return value from global cache (if present)
           Object global = globalCache.get(key);
           if (global != null) {
  @@ -142,9 +149,11 @@
                   logger.log(txId + " added '" + key + "'", logChannel, Logger.DEBUG);
               }
           } else {
  -            globalCache.put(key, value);
  -            if (loggingEnabled) {
  -                logger.log("Added '" + key + "'", logChannel, Logger.DEBUG);
  +            if (globalCache != null) {
  +                globalCache.put(key, value);
  +                if (loggingEnabled) {
  +                    logger.log("Added '" + key + "'", logChannel, Logger.DEBUG);
  +                }
               }
           }
       }
  @@ -163,9 +172,11 @@
                   logger.log(txId + " removed '" + key + "'", logChannel, 
Logger.DEBUG);
               }
           } else {
  -            globalCache.remove(key);
  -            if (loggingEnabled) {
  -                logger.log("Removed '" + key + "'", logChannel, Logger.DEBUG);
  +            if (globalCache != null) {
  +                globalCache.remove(key);
  +                if (loggingEnabled) {
  +                    logger.log("Removed '" + key + "'", logChannel, Logger.DEBUG);
  +                }
               }
           }
       }
  @@ -201,32 +212,34 @@
   
       public synchronized void commit(Object txId) {
           if (txId != null) {
  -            // apply local changes and deletes (is atomic as we have a global lock 
on this TxCache)
   
  -            Map changeCache = (Map) txChangeCaches.get(txId);
  -            for (Iterator it = changeCache.entrySet().iterator(); it.hasNext();) {
  -                Map.Entry entry = (Map.Entry) it.next();
  -                globalCache.put(entry.getKey(), entry.getValue());
  -            }
  +            if (globalCache != null) {
  +                // apply local changes and deletes (is atomic as we have a global 
lock on this TxCache)
   
  -            Set deleteCache = (Set) txDeleteCaches.get(txId);
  -            for (Iterator it = deleteCache.iterator(); it.hasNext();) {
  -                Object key = it.next();
  -                globalCache.remove(key);
  -            }
  +                Map changeCache = (Map) txChangeCaches.get(txId);
  +                for (Iterator it = changeCache.entrySet().iterator(); 
it.hasNext();) {
  +                    Map.Entry entry = (Map.Entry) it.next();
  +                    globalCache.put(entry.getKey(), entry.getValue());
  +                }
   
  -            if (loggingEnabled) {
  -                logger.log(
  -                    txId
  -                        + " committed "
  -                        + changeCache.size()
  -                        + " changes and "
  -                        + deleteCache.size()
  -                        + " scheduled deletes",
  -                    logChannel,
  -                    Logger.DEBUG);
  +                Set deleteCache = (Set) txDeleteCaches.get(txId);
  +                for (Iterator it = deleteCache.iterator(); it.hasNext();) {
  +                    Object key = it.next();
  +                    globalCache.remove(key);
  +                }
  +
  +                if (loggingEnabled) {
  +                    logger.log(
  +                        txId
  +                            + " committed "
  +                            + changeCache.size()
  +                            + " changes and "
  +                            + deleteCache.size()
  +                            + " scheduled deletes",
  +                        logChannel,
  +                        Logger.DEBUG);
  +                }
               }
  -
               // finally forget about tx
               forget(txId);
           }
  @@ -267,7 +280,7 @@
                       + " / "
                       + misses
                       + " / "
  -                    + globalCache.size());
  +                    + (globalCache != null ? globalCache.size() : -1));
               logger.log(log.toString(), logChannel, Logger.DEBUG);
           }
       }
  
  
  
  1.5       +39 -4     
jakarta-slide/src/share/org/apache/slide/store/ExtendedStore.java
  
  Index: ExtendedStore.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-slide/src/share/org/apache/slide/store/ExtendedStore.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ExtendedStore.java        11 Feb 2004 11:30:18 -0000      1.4
  +++ ExtendedStore.java        20 Feb 2004 11:13:23 -0000      1.5
  @@ -99,6 +99,12 @@
       protected static final long DEFAULT_MAX_CONTENT_BYTES_PER_ENTRY = 50000; // 50 K
       protected static final String MAX_CONTENT_BYTES_PER_ENTRY_PARAMETER = 
"max-content-bytes-per-entry";
   
  +    protected static final String CACHE_MODE_PARAMETER = "cache-mode";
  +    protected static final String CACHE_MODE_FULL = "full";
  +    protected static final String CACHE_MODE_LOCAL = "cluster";
  +    protected static final String CACHE_MODE_FULL_NO_TX = "isolation-shadow";
  +    protected static final String DEFAULT_CACHE_MODE = CACHE_MODE_FULL;
  +
       // there might be at least one active transaction branch per thread
       protected ThreadLocal activeTransactionBranch = new ThreadLocal();
   
  @@ -274,6 +280,35 @@
               "Setting maximum byte size for content cache entry for store " + 
getName() + " to " + maxByteSizePerEntry,
               LOG_CHANNEL,
               Logger.INFO);
  +
  +        String cacheModeString = (String) parameters.get(CACHE_MODE_PARAMETER);
  +        if (cacheModeString == null) cacheModeString = DEFAULT_CACHE_MODE;
  +        cacheModeString = cacheModeString.trim();
  +
  +        boolean noGlobalCache;
  +        if (cacheModeString.equals(CACHE_MODE_FULL)) {
  +            noGlobalCache = false;
  +            getLogger().log("Enabling full caching causing low isolation", 
LOG_CHANNEL, Logger.INFO);
  +        } else if (cacheModeString.equals(CACHE_MODE_LOCAL)) {
  +            noGlobalCache = true;
  +            getLogger().log("Disabling global cache to shadow store isolation and 
allow for clustering", LOG_CHANNEL, Logger.INFO);
  +        } else if (cacheModeString.equals(CACHE_MODE_FULL_NO_TX)) {
  +            noGlobalCache = true;
  +            getLogger().log("Cache mode isolation shadow not yet implemented! Using 
cluster mode instead...", LOG_CHANNEL, Logger.WARNING);
  +        } else {
  +            noGlobalCache = false;
  +            getLogger().log("Unknown cache mode "+cacheModeString+" Using full mode 
instead...", LOG_CHANNEL, Logger.WARNING);
  +        }
  +
  +        // disable global cache if desired        
  +        if (noGlobalCache) {
  +            globalObjectCacheSize = -1;
  +            globalPermissionCacheSize = -1;
  +            globalLockCacheSize = -1;
  +            globalDescrtiptorsCacheSize = -1;
  +            globalDescrtiptorCacheSize = -1;
  +            contentCachingEnabled = false;
  +        }
   
           init(
               globalObjectCacheSize,
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to