From ade7da0c99920e6f4d4de645c87925a1104bd5c8 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Wed, 29 Feb 2012 13:39:50 +0000
Subject: [PATCH] LMS-2761 chaching improved

SVN: 24590
---
 .../openbis/dss/generic/server/ftp/Cache.java | 52 +++++++++++++++----
 .../generic/server/ftp/DSSFileSystemView.java |  3 +-
 .../dss/generic/server/ftp/FtpServer.java     |  4 +-
 ...plateBasedDataSetResourceResolverTest.java | 11 +++-
 4 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/Cache.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/Cache.java
index 5ef7dc81c66..c415c009016 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/Cache.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/Cache.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.dss.generic.server.ftp;
 import java.util.HashMap;
 import java.util.Map;
 
+import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
@@ -31,38 +32,71 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
  */
 public class Cache
 {
-    private final Map<String, DataSet> dataSets = new HashMap<String, DataSet>();
-    private final Map<String, ExternalData> externalData = new HashMap<String, ExternalData>();
-    private final Map<String, Experiment> experiments = new HashMap<String, Experiment>();
+    private static final long LIVE_TIME = 1000;
+    
+    private static final class TimeStampedObject<T>
+    {
+        private final long timestamp;
+        private final T object;
+        public TimeStampedObject(T object, long timestamp)
+        {
+            this.object = object;
+            this.timestamp = timestamp;
+        }
+    }
+    
+    private final Map<String, TimeStampedObject<DataSet>> dataSets = new HashMap<String, Cache.TimeStampedObject<DataSet>>();
+    private final Map<String, TimeStampedObject<ExternalData>> externalData = new HashMap<String, Cache.TimeStampedObject<ExternalData>>();
+    private final Map<String, TimeStampedObject<Experiment>> experiments = new HashMap<String, Cache.TimeStampedObject<Experiment>>();
+    
+    private final ITimeProvider timeProvider;
+    
+    public Cache(ITimeProvider timeProvider)
+    {
+        this.timeProvider = timeProvider;
+    }
     
     void putDataSet(DataSet dataSet)
     {
-        dataSets.put(dataSet.getCode(), dataSet);
+        dataSets.put(dataSet.getCode(), timestamp(dataSet));
     }
     
     DataSet getDataSet(String dataSetCode)
     {
-        return dataSets.get(dataSetCode);
+        return getObject(dataSets, dataSetCode);
     }
 
     ExternalData getExternalData(String code)
     {
-        return externalData.get(code);
+        return getObject(externalData, code);
     }
 
     void putDataSet(ExternalData dataSet)
     {
-        externalData.put(dataSet.getCode(), dataSet);
+        externalData.put(dataSet.getCode(), timestamp(dataSet));
     }
 
     Experiment getExperiment(String experimentId)
     {
-        return experiments.get(experimentId);
+        return getObject(experiments, experimentId);
     }
 
     void putDataSet(Experiment experiment)
     {
-        experiments.put(experiment.getIdentifier(), experiment);
+        experiments.put(experiment.getIdentifier(), timestamp(experiment));
+    }
+
+    private <T> TimeStampedObject<T> timestamp(T object)
+    {
+        return new TimeStampedObject<T>(object, timeProvider.getTimeInMilliseconds());
+    }
+
+    private <T> T getObject(Map<String, TimeStampedObject<T>> map, String key)
+    {
+        TimeStampedObject<T> timeStampedObject = map.get(key);
+        return timeStampedObject == null
+                || timeProvider.getTimeInMilliseconds() - timeStampedObject.timestamp > LIVE_TIME ? null
+                : timeStampedObject.object;
     }
     
 }
\ No newline at end of file
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java
index 49f25bdab30..d847a891424 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/DSSFileSystemView.java
@@ -36,6 +36,7 @@ import org.apache.log4j.Logger;
 import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.utilities.SystemTimeProvider;
 import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.util.Key;
@@ -132,7 +133,7 @@ public class DSSFileSystemView implements FileSystemView
 
     public FtpFile getFile(String path) throws FtpException
     {
-        return getFile(path, new Cache());
+        return getFile(path, new Cache(SystemTimeProvider.SYSTEM_TIME_PROVIDER));
     }
     
     public FtpFile getFile(String path, Cache cache) throws FtpException
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java
index 8f99c0b1bb4..eb6dc0e33ea 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java
@@ -74,6 +74,7 @@ import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.utilities.SystemTimeProvider;
 import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 
@@ -271,6 +272,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File
             final DSSFileSystemView view = createFileSystemView(user);
             return new org.apache.sshd.server.FileSystemView()
                 {
+                    private Cache cache = new Cache(SystemTimeProvider.SYSTEM_TIME_PROVIDER);
                     
                     public SshFile getFile(SshFile baseDir, String file)
                     {
@@ -279,7 +281,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File
                     
                     public SshFile getFile(String file)
                     {
-                        return new FileView(view, file, new Cache());
+                        return new FileView(view, file, cache);
                     }
                 };
         } catch (FtpException ex)
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java
index 9b569069287..ef3a41b2a02 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java
@@ -44,6 +44,7 @@ import ch.systemsx.cisd.common.io.hierarchical_content.api.IHierarchicalContent;
 import ch.systemsx.cisd.common.io.hierarchical_content.api.IHierarchicalContentNode;
 import ch.systemsx.cisd.common.test.TrackingMockery;
 import ch.systemsx.cisd.common.utilities.IDelegatedAction;
+import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.Cache;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpConstants;
 import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpPathResolverContext;
@@ -151,6 +152,14 @@ public class TemplateBasedDataSetResourceResolverTest extends AbstractFileSystem
 
     private DataSet ds3;
 
+    private ITimeProvider timeProvider = new ITimeProvider()
+        {
+            public long getTimeInMilliseconds()
+            {
+                return 0;
+            }
+        };
+
     @Override
     @BeforeMethod
     public void setUp()
@@ -170,7 +179,7 @@ public class TemplateBasedDataSetResourceResolverTest extends AbstractFileSystem
 
         resolverContext =
                 new FtpPathResolverContext(SESSION_TOKEN, service, generalInfoService, null,
-                        new Cache());
+                        new Cache(timeProvider));
         context.checking(new Expectations()
             {
                 {
-- 
GitLab