From 192711a0a30c377ed34005a85482d7c535da7551 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Mon, 20 May 2024 16:13:06 -0700 Subject: [PATCH 1/3] Eliminate DbCache --- api/src/org/labkey/api/ApiModule.java | 29 ++- .../org/labkey/api/cache/CachingTestCase.java | 13 -- api/src/org/labkey/api/cache/DbCache.java | 184 ------------------ .../labkey/api/data/AbstractTableInfo.java | 2 +- api/src/org/labkey/api/data/Table.java | 25 +-- api/src/org/labkey/api/data/TableInfo.java | 6 +- .../org/labkey/api/exp/OntologyManager.java | 2 +- .../api/query/DefaultQueryUpdateService.java | 9 +- .../labkey/core/admin/AdminController.java | 1 - .../api/ExpIdentifiableBaseImpl.java | 3 - .../org/labkey/experiment/api/ExpRunImpl.java | 3 - .../experiment/api/ExperimentServiceImpl.java | 47 +---- .../labkey/pipeline/api/PipelineManager.java | 9 +- .../specimen/SpecimenRequestManager.java | 2 - .../labkey/specimen/SpecimenServiceImpl.java | 4 - .../specimen/actions/SpecimenController.java | 2 +- .../importer/SpecimenSettingsImporter.java | 6 +- .../specimen/settings/SettingsManager.java | 14 +- .../view/SpecimenToolsWebPartFactory.java | 2 +- .../src/org/labkey/specimen/view/webPart.jsp | 2 +- .../org/labkey/api/study/QueryHelper.java | 7 - .../org/labkey/api/study/StudyCache.java | 75 ++----- .../importer/DefaultStudyDesignImporter.java | 8 +- .../org/labkey/study/model/StudyManager.java | 65 +------ .../labkey/study/model/TreatmentManager.java | 6 +- .../study/query/StudyPropertiesTable.java | 12 +- .../query/StudyPropertiesUpdateService.java | 2 - 27 files changed, 71 insertions(+), 469 deletions(-) delete mode 100644 api/src/org/labkey/api/cache/CachingTestCase.java delete mode 100644 api/src/org/labkey/api/cache/DbCache.java diff --git a/api/src/org/labkey/api/ApiModule.java b/api/src/org/labkey/api/ApiModule.java index 3dfc2707131..f6c60b8f9d7 100644 --- a/api/src/org/labkey/api/ApiModule.java +++ b/api/src/org/labkey/api/ApiModule.java @@ -32,7 +32,6 @@ import org.labkey.api.attachments.LookAndFeelResourceType; import org.labkey.api.attachments.SecureDocumentType; import org.labkey.api.cache.BlockingCache; -import org.labkey.api.cache.CachingTestCase; import org.labkey.api.collections.ArrayListMap; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.collections.CaseInsensitiveHashSet; @@ -139,7 +138,32 @@ import org.labkey.api.settings.ExperimentalFeatureStartupListener; import org.labkey.api.settings.LookAndFeelProperties; import org.labkey.api.settings.WriteableLookAndFeelProperties; -import org.labkey.api.util.*; +import org.labkey.api.util.ChecksumUtil; +import org.labkey.api.util.Compress; +import org.labkey.api.util.ContextListener; +import org.labkey.api.util.DateUtil; +import org.labkey.api.util.DomTestCase; +import org.labkey.api.util.ExceptionUtil; +import org.labkey.api.util.ExtUtil; +import org.labkey.api.util.FileType; +import org.labkey.api.util.FileUtil; +import org.labkey.api.util.HelpTopic; +import org.labkey.api.util.JSoupUtil; +import org.labkey.api.util.JsonUtil; +import org.labkey.api.util.JspTestCase; +import org.labkey.api.util.MailHelper; +import org.labkey.api.util.MemTracker; +import org.labkey.api.util.MimeMap; +import org.labkey.api.util.NumberUtilsLabKey; +import org.labkey.api.util.PageFlowUtil; +import org.labkey.api.util.Pair; +import org.labkey.api.util.Path; +import org.labkey.api.util.ResultSetUtil; +import org.labkey.api.util.SessionHelper; +import org.labkey.api.util.StringExpressionFactory; +import org.labkey.api.util.StringUtilsLabKey; +import org.labkey.api.util.SystemMaintenance; +import org.labkey.api.util.URLHelper; import org.labkey.api.util.emailTemplate.EmailTemplate; import org.labkey.api.view.ActionURL; import org.labkey.api.view.FileServlet; @@ -367,7 +391,6 @@ public void registerServlets(ServletContext servletCtx) AppPropsTestCase.class, AtomicDatabaseInteger.TestCase.class, BlockingCache.BlockingCacheTest.class, - CachingTestCase.class, CompareType.TestCase.class, ContainerDisplayColumn.TestCase.class, ContainerFilter.TestCase.class, diff --git a/api/src/org/labkey/api/cache/CachingTestCase.java b/api/src/org/labkey/api/cache/CachingTestCase.java deleted file mode 100644 index ac654316ff3..00000000000 --- a/api/src/org/labkey/api/cache/CachingTestCase.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.labkey.api.cache; - -import org.junit.Assert; -import org.junit.Test; - -public class CachingTestCase extends Assert -{ - @Test - public void testCaching() - { - DbCache.logUnmatched(); - } -} diff --git a/api/src/org/labkey/api/cache/DbCache.java b/api/src/org/labkey/api/cache/DbCache.java deleted file mode 100644 index d2e17c6f5d0..00000000000 --- a/api/src/org/labkey/api/cache/DbCache.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2010-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.api.cache; - -import org.apache.commons.collections4.Bag; -import org.apache.commons.collections4.bag.HashBag; -import org.apache.logging.log4j.Logger; -import org.labkey.api.data.DatabaseCache; -import org.labkey.api.data.TableInfo; -import org.labkey.api.util.ExceptionUtil; -import org.labkey.api.util.Path; -import org.labkey.api.util.logging.LogHelper; - -import java.util.HashMap; -import java.util.Map; - -/** - * Don't use this! Use CacheManager.getCache() or DatabaseCache instead. DbCache associates a DatabaseCache with each - * participating TableInfo. The Table layer then invalidates the entire cache anytime it touches (insert, update, delete) - * that TableInfo. This is easy, but very inefficient. Managers should use DatabaseCaches directly and handle - * invalidation themselves. - */ -@Deprecated -public class DbCache -{ - private static final Logger LOG = LogHelper.getLogger(DbCache.class, "DbCache invalidations"); - private static final Map> CACHES = new HashMap<>(10); - - public static DatabaseCache getCache(TableInfo tinfo, boolean create) - { - Path cacheKey = tinfo.getNotificationKey(); - assert null != cacheKey : "DbCache not supported for " + tinfo; - - synchronized(CACHES) - { - DatabaseCache cache = CACHES.get(cacheKey); - - if (null == cache && create) - { - cache = new DatabaseCache<>(tinfo.getSchema().getScope(), tinfo.getCacheSize(), "DbCache: " + tinfo.getName()); - CACHES.put(cacheKey, cache); - } - - return cache; - } - } - - public static void put(TableInfo tinfo, String name, Object obj) - { - DatabaseCache cache = getCache(tinfo, true); - cache.put(name, obj); - } - - public static void put(TableInfo tinfo, String name, Object obj, long millisToLive) - { - DatabaseCache cache = getCache(tinfo, true); - cache.put(name, obj, millisToLive); - } - - public static Object get(TableInfo tinfo, String name) - { - DatabaseCache cache = getCache(tinfo, false); - return null == cache ? null : cache.get(name); - } - - public static void remove(TableInfo tinfo, String name) - { - DatabaseCache cache = getCache(tinfo, false); - if (null != cache) - cache.remove(name); - } - - /** used by Table */ - public static void invalidateAll(TableInfo tinfo) - { - DatabaseCache cache = CACHES.get(tinfo.getNotificationKey()); - if (null != cache) - { - trackInvalidate(tinfo); - cache.clear(); - } - } - - public static void clear(TableInfo tinfo) - { - DatabaseCache cache = getCache(tinfo, false); - if (null != cache) - { - trackInvalidate(tinfo); - cache.clear(); - } - } - - public static void removeUsingPrefix(TableInfo tinfo, String name) - { - DatabaseCache cache = getCache(tinfo, false); - if (null != cache) - cache.removeUsingFilter(new Cache.StringPrefixFilter(name)); - } - - /** - * Everything below is temporary, meant to help eradicate the use of DbCache. If a TableInfo is deemed "interesting" - * (it's in the process of being migrated): - * - Each call to invalidateAll() or clear() causes its stack trace to be added to the tracking bag - * - Each call to trackRemove() causes its stack trace to be removed from the tracking bag - * A remove that's unsuccessful indicates no corresponding invalidateAll(), so log that. Anything left in the bag - * indicates invalidateAll()/clear() calls with no corresponding remove. Use this to migrate a DbCache to our normal - * DatabaseCache pattern, with explicit removes for invalidation. Leave the DbCache in place (until migration is - * complete) and add calls to trackRemove() immediately after Table.insert(), Table.update(), and Table.delete() - * calls. Ensure that nothing is left in the bag, meaning all Table-initiated invalidateAll() calls have - * corresponding removes on the new cache. See CachingTestCase as an example. - */ - - private static final Bag TRACKING_BAG = new HashBag<>(); - - private static boolean isInteresting(TableInfo tinfo) - { - return getCache(tinfo, false) != null; - } - - public static void trackInvalidate(TableInfo tinfo) - { - if (isInteresting(tinfo)) - { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - int linesToTrim = 2; - - // Trim all Table lines, if present - for (int i = 2; i < stackTrace.length; i++) - { - if ("Table.java".equals(stackTrace[i].getFileName())) - linesToTrim = i; - else if (linesToTrim > 2) - break; - } - - String key = tinfo.getName() + ExceptionUtil.renderStackTrace(stackTrace, linesToTrim + 1); - TRACKING_BAG.add(key); - } - } - - public static void trackRemove(TableInfo tinfo) - { - if (isInteresting(tinfo)) - { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - String trimmed = ExceptionUtil.renderStackTrace(stackTrace, 2); - - // Subtract one from the first line number so it matches the Table.* line (so the stack traces match exactly) - int from = trimmed.indexOf(':') + 1; - int to = trimmed.indexOf(')', from); - String lineNumber = trimmed.substring(from, to); - String key = tinfo.getName() + trimmed.replaceFirst(lineNumber, String.valueOf(Integer.valueOf(lineNumber) - 1)); - if (!TRACKING_BAG.remove(key, 1)) - LOG.info("Failed to remove " + key); - } - } - - public static void logUnmatched() - { - if (TRACKING_BAG.isEmpty()) - { - LOG.info("No unmatched cache removes"); - } - else - { - TRACKING_BAG.uniqueSet().forEach(key -> LOG.error("Unmatched {}", key)); - } - } -} diff --git a/api/src/org/labkey/api/data/AbstractTableInfo.java b/api/src/org/labkey/api/data/AbstractTableInfo.java index 4d3fedf6e69..665755b4cc5 100644 --- a/api/src/org/labkey/api/data/AbstractTableInfo.java +++ b/api/src/org/labkey/api/data/AbstractTableInfo.java @@ -1880,7 +1880,7 @@ public void fireRowTrigger(Container c, User user, TriggerType type, boolean bef } - /** TableInfo does not support DbCache by default */ + /** TableInfo does not support QueryHelper by default */ @Override public Path getNotificationKey() { diff --git a/api/src/org/labkey/api/data/Table.java b/api/src/org/labkey/api/data/Table.java index 8c93bfc64c2..cfbfeeb4c16 100644 --- a/api/src/org/labkey/api/data/Table.java +++ b/api/src/org/labkey/api/data/Table.java @@ -25,7 +25,6 @@ import org.jetbrains.annotations.Nullable; import org.junit.Assert; import org.junit.Test; -import org.labkey.api.cache.DbCache; import org.labkey.api.collections.BoundMap; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.collections.CaseInsensitiveHashSet; @@ -917,8 +916,6 @@ else if (column.isAutoIncrement()) _copyInsertSpecialFields(returnObject, fields); _copyUpdateSpecialFields(table, returnObject, fields); - - notifyTableUpdate(table); } catch(SQLException e) { @@ -1098,7 +1095,6 @@ else if (pkVals instanceof Map) } _copyUpdateSpecialFields(table, fieldsIn, fields); - notifyTableUpdate(table); } catch (OptimisticConflictException e) { @@ -1140,9 +1136,7 @@ public static int delete(TableInfo table) { assert (table.getTableType() != DatabaseTableType.NOT_IN_DB): (table.getName() + " is not in the physical database."); SqlExecutor sqlExecutor = new SqlExecutor(table.getSchema()); - int result = sqlExecutor.execute("DELETE FROM " + table.getSelectName()); - notifyTableUpdate(table); - return result; + return sqlExecutor.execute("DELETE FROM " + table.getSelectName()); } public static int delete(TableInfo table, Filter filter) @@ -1152,10 +1146,8 @@ public static int delete(TableInfo table, Filter filter) SQLFragment where = filter.getSQLFragment(table.getSqlDialect(), null, createColumnMap(table,null)); SQLFragment deleteSQL = new SQLFragment("DELETE FROM ").append(table).append("\n\t").append(where); - int result = new SqlExecutor(table.getSchema()).execute(deleteSQL); - notifyTableUpdate(table); - return result; + return new SqlExecutor(table.getSchema()).execute(deleteSQL); } public static void truncate(TableInfo table) @@ -1163,16 +1155,13 @@ public static void truncate(TableInfo table) assert (table.getTableType() != DatabaseTableType.NOT_IN_DB): (table.getName() + " is not in the physical database."); SqlExecutor sqlExecutor = new SqlExecutor(table.getSchema()); sqlExecutor.execute(table.getSqlDialect().getTruncateSql(table.getSelectName())); - notifyTableUpdate(table); } - public static SQLFragment getSelectSQL(TableInfo table, @Nullable Collection columns, @Nullable Filter filter, @Nullable Sort sort) { return QueryService.get().getSelectSQL(table, columns, filter, sort, ALL_ROWS, NO_OFFSET, false); } - public static void ensureRequiredColumns(TableInfo table, Map cols, @Nullable Filter filter, @Nullable Sort sort, @Nullable List aggregates) { List allColumns = table.getColumns(); @@ -1219,15 +1208,6 @@ public static void snapshot(TableInfo tinfo, String tableName) new SqlExecutor(tinfo.getSchema()).execute(sqlSelectInto); } - - // Table modification - - public static void notifyTableUpdate(/*String operation,*/ TableInfo table/*, Container c*/) - { - DbCache.invalidateAll(table); - } - - private static void _logQuery(Level level, @Nullable SQLFragment sqlFragment, @Nullable Connection conn) { if (!_log.isEnabled(level) || null == sqlFragment) @@ -1281,7 +1261,6 @@ static void _appendTableStackTrace(StringBuilder sb, int count) } } - public static class TestCase extends Assert { private static final CoreSchema _core = CoreSchema.getInstance(); diff --git a/api/src/org/labkey/api/data/TableInfo.java b/api/src/org/labkey/api/data/TableInfo.java index b584f0181f6..e7a531e6580 100644 --- a/api/src/org/labkey/api/data/TableInfo.java +++ b/api/src/org/labkey/api/data/TableInfo.java @@ -607,10 +607,8 @@ void fireRowTrigger(Container c, User user, TriggerType type, boolean before, in default boolean hasDbTriggers() { return false; } /** - * TableInfos that can be associated with a DbCache need a reliable key other than a TableInfo instance. - * Return null if DbCache is not supported. - * - * We should probably kill DbCache, but let's fix this for now (https://www.labkey.org/issues/home/Developer/issues/details.view?issueId=10508) + * TableInfos that can be associated with a QueryHelper need a reliable key other than a TableInfo instance. + * Return null if QueryHelper is not supported. */ Path getNotificationKey(); diff --git a/api/src/org/labkey/api/exp/OntologyManager.java b/api/src/org/labkey/api/exp/OntologyManager.java index 715c88cde81..42c5bc094c1 100644 --- a/api/src/org/labkey/api/exp/OntologyManager.java +++ b/api/src/org/labkey/api/exp/OntologyManager.java @@ -2475,7 +2475,7 @@ public static Pair getCacheKey(String uri, Container c) return Pair.of(uri, projId); } - //TODO: DbCache semantics. This loads the cache but does not fetch cause need to get them all together + //TODO: Cache semantics. This loads the cache but does not fetch cause need to get them all together public static List getPropertiesForType(String typeURI, Container c) { List> propertyURIs = DOMAIN_PROPERTIES_CACHE.get(getCacheKey(typeURI, c)); diff --git a/api/src/org/labkey/api/query/DefaultQueryUpdateService.java b/api/src/org/labkey/api/query/DefaultQueryUpdateService.java index b141479e85b..d317becb321 100644 --- a/api/src/org/labkey/api/query/DefaultQueryUpdateService.java +++ b/api/src/org/labkey/api/query/DefaultQueryUpdateService.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.attachments.AttachmentFile; -import org.labkey.api.cache.DbCache; import org.labkey.api.collections.ArrayListMap; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.data.ColumnInfo; @@ -335,9 +334,7 @@ protected Map _insert(User user, Container c, Map ret = Table.insert(user, getDbTable(), row); - if (getDbTable().getName().equals("AssaySpecimen")) { DbCache.trackRemove(getDbTable()); } - return ret; + return Table.insert(user, getDbTable(), row); } catch (RuntimeValidationException e) { @@ -566,9 +563,7 @@ protected Map _update(User user, Container c, Map ret = Table.update(user, getDbTable(), row, keys); - if (getDbTable().getName().equals("AssaySpecimen")) DbCache.trackRemove(getDbTable()); // Handled in caller (TreatmentManager.saveAssaySpecimen()) - return ret; + return Table.update(user, getDbTable(), row, keys); // Cache-invalidation handled in caller (TreatmentManager.saveAssaySpecimen()) } // Get value from row map where the keys are column names. diff --git a/core/src/org/labkey/core/admin/AdminController.java b/core/src/org/labkey/core/admin/AdminController.java index 305d182f05e..d0210826167 100644 --- a/core/src/org/labkey/core/admin/AdminController.java +++ b/core/src/org/labkey/core/admin/AdminController.java @@ -3040,7 +3040,6 @@ private void appendStats(HtmlStringBuilder html, String title, List private static final List PREFIXES_TO_SKIP = List.of( "java.base/java.lang.Thread.getStackTrace", "org.labkey.api.cache.CacheManager", - "org.labkey.api.cache.DbCache", "org.labkey.api.cache.Throttle", "org.labkey.api.data.DatabaseCache", "org.labkey.api.module.ModuleResourceCache" diff --git a/experiment/src/org/labkey/experiment/api/ExpIdentifiableBaseImpl.java b/experiment/src/org/labkey/experiment/api/ExpIdentifiableBaseImpl.java index 4b3de3523a2..b8d762ac5c4 100644 --- a/experiment/src/org/labkey/experiment/api/ExpIdentifiableBaseImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpIdentifiableBaseImpl.java @@ -17,7 +17,6 @@ package org.labkey.experiment.api; import org.jetbrains.annotations.Nullable; -import org.labkey.api.cache.DbCache; import org.labkey.api.data.DbScope; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.SqlSelector; @@ -133,7 +132,6 @@ protected void save(User user, TableInfo table, boolean ensureObject, boolean is _object.setObjectId(_objectId); } _object = Table.insert(user, table, _object); - if (this instanceof ExpRunImpl) DbCache.trackRemove(table); assert !ensureObject || !(_object instanceof IdentifiableEntity) || _objectId == _object.getObjectId(); } else @@ -149,7 +147,6 @@ protected void save(User user, TableInfo table, boolean ensureObject, boolean is } _object = Table.update(user, table, _object, getRowId()); - if (table.getName().equals("ExperimentRun")) DbCache.trackRemove(table); // Handled in override if (_prevLsid != null && ensureObject) { diff --git a/experiment/src/org/labkey/experiment/api/ExpRunImpl.java b/experiment/src/org/labkey/experiment/api/ExpRunImpl.java index ebeeba70984..11bc992ff36 100644 --- a/experiment/src/org/labkey/experiment/api/ExpRunImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpRunImpl.java @@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.assay.AssayFileWriter; -import org.labkey.api.cache.DbCache; import org.labkey.api.cloud.CloudStoreService; import org.labkey.api.data.Container; import org.labkey.api.data.DbScope; @@ -548,7 +547,6 @@ public void deleteProtocolApplications(List datasToDelete, User use final ExperimentServiceImpl svc = ExperimentServiceImpl.get(); final SqlDialect dialect = svc.getSchema().getSqlDialect(); - DbCache.remove(svc.getTinfoExperimentRun(), svc.getCacheKey(getLSID())); ExperimentServiceImpl.get().invalidateExperimentRun(getLSID()); deleteProtocolApplicationProvenance(); @@ -931,7 +929,6 @@ public List getAllDataUsedByRun() return ExpDataImpl.fromDatas(new SqlSelector(ExperimentServiceImpl.get().getSchema(), sql).getArrayList(Data.class)); } - public void clearCache() { _populated = false; diff --git a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java index 9697ece640b..68585282f52 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java @@ -54,7 +54,6 @@ import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheLoader; import org.labkey.api.cache.CacheManager; -import org.labkey.api.cache.DbCache; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.collections.Sets; @@ -4144,51 +4143,7 @@ public List getExperiments(Container container, User user, bo public ExperimentRun getExperimentRun(String lsid) { - ExperimentRun runOld = getExperimentRunOld(lsid); - ExperimentRun runNew = getExperimentRunNew(lsid); - - if (null != runOld) - { - assert runOld.equals(runNew) : "Experiment runs are not equal!"; - - assert Objects.equals(runOld.getComments(), runNew.getComments()); - assert Objects.equals(runOld.getBatchId(), runNew.getBatchId()); - assert Objects.equals(runOld.getJobId(), runNew.getJobId()); - assert Objects.equals(runOld.getFilePathRoot(), runNew.getFilePathRoot()); - assert Objects.equals(runOld.getName(), runNew.getName()); - assert Objects.equals(runOld.getWorkflowTask(), runNew.getWorkflowTask()); - assert Objects.equals(runOld.getModified(), runNew.getModified()); - } - else - { - if (runNew != null) - { - DbCache.logUnmatched(); - throw new IllegalStateException(runOld + " != " + runNew); - } - } - - return runOld; - } - - private ExperimentRun getExperimentRunOld(String LSID) - { - //Use main cache so updates/deletes through table layer get handled - String cacheKey = getCacheKey(LSID); - ExperimentRun run = (ExperimentRun) DbCache.get(getTinfoExperimentRun(), cacheKey); - if (null != run) - return run; - - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("LSID"), LSID); - run = new TableSelector(getTinfoExperimentRun(), filter, null).getObject(ExperimentRun.class); - if (null != run) - DbCache.put(getTinfoExperimentRun(), cacheKey, run); - return run; - } - - private ExperimentRun getExperimentRunNew(String LSID) - { - return EXPERIMENT_RUN_CACHE.get(LSID); + return EXPERIMENT_RUN_CACHE.get(lsid); } private class ExperimentRunCacheLoader implements CacheLoader diff --git a/pipeline/src/org/labkey/pipeline/api/PipelineManager.java b/pipeline/src/org/labkey/pipeline/api/PipelineManager.java index 55d355669ce..5238540801e 100644 --- a/pipeline/src/org/labkey/pipeline/api/PipelineManager.java +++ b/pipeline/src/org/labkey/pipeline/api/PipelineManager.java @@ -15,6 +15,9 @@ */ package org.labkey.pipeline.api; +import jakarta.mail.Address; +import jakarta.mail.Message; +import jakarta.mail.internet.MimeMessage; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,7 +28,6 @@ import org.labkey.api.admin.InvalidFileException; import org.labkey.api.cache.BlockingCache; import org.labkey.api.cache.CacheManager; -import org.labkey.api.cache.DbCache; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.DbScope; @@ -81,9 +83,6 @@ import org.springframework.validation.BindException; import org.springframework.validation.Errors; -import jakarta.mail.Address; -import jakarta.mail.Message; -import jakarta.mail.internet.MimeMessage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -222,8 +221,6 @@ static public void purge(Container container, User user) try (DbScope.Transaction transaction = ExperimentService.get().ensureTransaction()) { new SqlExecutor(PipelineSchema.getInstance().getSchema()).execute(sql); - DbCache.clear(ExperimentService.get().getTinfoExperimentRun()); - DbCache.trackRemove(ExperimentService.get().getTinfoExperimentRun()); ExperimentService.get().clearCaches(); ContainerUtil.purgeTable(pipeline.getTableInfoStatusFiles(), container, "Container"); diff --git a/specimen/src/org/labkey/specimen/SpecimenRequestManager.java b/specimen/src/org/labkey/specimen/SpecimenRequestManager.java index 2bcfff0f424..0a746b050ff 100644 --- a/specimen/src/org/labkey/specimen/SpecimenRequestManager.java +++ b/specimen/src/org/labkey/specimen/SpecimenRequestManager.java @@ -10,7 +10,6 @@ import org.labkey.api.cache.BlockingCache; import org.labkey.api.cache.CacheLoader; import org.labkey.api.cache.CacheManager; -import org.labkey.api.cache.DbCache; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.DatabaseCache; @@ -114,7 +113,6 @@ public List getRequestStatuses(Container c, User user) try (var ignore = SpringActionController.ignoreSqlUpdates()) { Table.insert(user, _requestStatusHelper.getTableInfo(), notYetSubmittedStatus); - DbCache.trackRemove(_requestStatusHelper.getTableInfo()); _requestStatusHelper.clearCache(c); } statuses = _requestStatusHelper.getList(c, "SortOrder"); diff --git a/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java b/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java index 6354073b5a1..be6a5beb3d8 100644 --- a/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java +++ b/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java @@ -20,7 +20,6 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.cache.DbCache; import org.labkey.api.data.Container; import org.labkey.api.data.DbSchema; import org.labkey.api.data.PropertyManager; @@ -479,15 +478,12 @@ public void deleteAllSpecimenData(Container c, Set set, User user) Table.delete(SpecimenSchema.get().getTableInfoSampleRequestSpecimen(), containerFilter); assert set.add(SpecimenSchema.get().getTableInfoSampleRequestSpecimen()); Table.delete(SpecimenSchema.get().getTableInfoSampleRequestEvent(), containerFilter); - DbCache.trackRemove(SpecimenSchema.get().getTableInfoSampleRequestEvent()); SpecimenRequestManager.get().clearRequestEventHelper(c); assert set.add(SpecimenSchema.get().getTableInfoSampleRequestEvent()); Table.delete(SpecimenSchema.get().getTableInfoSampleRequest(), containerFilter); - DbCache.trackRemove(SpecimenSchema.get().getTableInfoSampleRequest()); SpecimenRequestManager.get().clearRequestHelper(c); assert set.add(SpecimenSchema.get().getTableInfoSampleRequest()); Table.delete(SpecimenSchema.get().getTableInfoSampleRequestStatus(), containerFilter); - DbCache.trackRemove(SpecimenSchema.get().getTableInfoSampleRequestStatus()); SpecimenRequestManager.get().clearRequestStatusHelper(c); assert set.add(SpecimenSchema.get().getTableInfoSampleRequestStatus()); diff --git a/specimen/src/org/labkey/specimen/actions/SpecimenController.java b/specimen/src/org/labkey/specimen/actions/SpecimenController.java index c8491c6bbcc..0a8064cae60 100644 --- a/specimen/src/org/labkey/specimen/actions/SpecimenController.java +++ b/specimen/src/org/labkey/specimen/actions/SpecimenController.java @@ -357,7 +357,7 @@ private ActionURL getManageStudyURL() public void ensureSpecimenRequestsConfigured(boolean checkExistingStatuses) { - if (!org.labkey.specimen.settings.SettingsManager.get().isSpecimenRequestEnabled(getContainer(), checkExistingStatuses)) + if (!org.labkey.specimen.settings.SettingsManager.get().isSpecimenRequestEnabled(getContainer(), checkExistingStatuses, getUser())) throw new RedirectException(new ActionURL(SpecimenRequestConfigRequiredAction.class, getContainer())); } diff --git a/specimen/src/org/labkey/specimen/importer/SpecimenSettingsImporter.java b/specimen/src/org/labkey/specimen/importer/SpecimenSettingsImporter.java index 4fd362a0d98..0468ecb7f14 100644 --- a/specimen/src/org/labkey/specimen/importer/SpecimenSettingsImporter.java +++ b/specimen/src/org/labkey/specimen/importer/SpecimenSettingsImporter.java @@ -62,16 +62,12 @@ import java.util.Map; import java.util.Set; -/** - * User: kevink - * Date: 6/13/13 - */ public class SpecimenSettingsImporter implements SimpleStudyImporter { @Override public Timing getTiming() { - return Timing.Late; // Can't setup specimen request actors until the locations have been created + return Timing.Late; // Can't set up specimen request actors until the locations have been created } @Override diff --git a/specimen/src/org/labkey/specimen/settings/SettingsManager.java b/specimen/src/org/labkey/specimen/settings/SettingsManager.java index 6adfb2d86eb..0319d6d53eb 100644 --- a/specimen/src/org/labkey/specimen/settings/SettingsManager.java +++ b/specimen/src/org/labkey/specimen/settings/SettingsManager.java @@ -3,13 +3,12 @@ import org.labkey.api.action.SpringActionController; import org.labkey.api.data.Container; import org.labkey.api.data.PropertyManager; +import org.labkey.api.security.User; import org.labkey.api.security.UserManager; import org.labkey.api.specimen.SpecimenRequestStatus; -import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.settings.DisplaySettings; import org.labkey.api.specimen.settings.RepositorySettings; import org.labkey.api.specimen.settings.StatusSettings; -import org.labkey.api.study.QueryHelper; import org.labkey.specimen.SpecimenRequestManager; import java.util.List; @@ -17,8 +16,6 @@ public class SettingsManager { - private final QueryHelper _requestStatusHelper; - private static final SettingsManager INSTANCE = new SettingsManager(); public static SettingsManager get() @@ -28,7 +25,6 @@ public static SettingsManager get() private SettingsManager() { - _requestStatusHelper = new QueryHelper<>(()-> SpecimenSchema.get().getTableInfoSampleRequestStatus(), SpecimenRequestStatus.class); } public RequestNotificationSettings getRequestNotificationSettings(Container container) @@ -81,12 +77,12 @@ public void saveRepositorySettings(Container container, RepositorySettings setti SpecimenRequestManager.get().clearGroupedValuesForColumn(container); // May have changed groupings } - public boolean isSpecimenRequestEnabled(Container container) + public boolean isSpecimenRequestEnabled(Container container, User user) { - return isSpecimenRequestEnabled(container, true); + return isSpecimenRequestEnabled(container, true, user); } - public boolean isSpecimenRequestEnabled(Container container, boolean checkExistingStatuses) + public boolean isSpecimenRequestEnabled(Container container, boolean checkExistingStatuses, User user) { if (!checkExistingStatuses) { @@ -96,7 +92,7 @@ public boolean isSpecimenRequestEnabled(Container container, boolean checkExisti { if (!org.labkey.api.specimen.settings.SettingsManager.get().getRepositorySettings(container).isEnableRequests()) return false; - List statuses = _requestStatusHelper.getList(container, "SortOrder"); + List statuses = SpecimenRequestManager.get().getRequestStatuses(container, user); return (statuses != null && statuses.size() > 1); } } diff --git a/specimen/src/org/labkey/specimen/view/SpecimenToolsWebPartFactory.java b/specimen/src/org/labkey/specimen/view/SpecimenToolsWebPartFactory.java index a49fedcf82f..84c655f649b 100644 --- a/specimen/src/org/labkey/specimen/view/SpecimenToolsWebPartFactory.java +++ b/specimen/src/org/labkey/specimen/view/SpecimenToolsWebPartFactory.java @@ -37,7 +37,7 @@ protected List getItems(ViewContext portalCtx) ActionURL vialSearchURL = ShowSearchAction.getShowSearchURL(portalCtx.getContainer(), true); items.add(new StudyToolsWebPart.Item("Vial Search", iconBase + "specimen_search.png", vialSearchURL)); - if (SettingsManager.get().isSpecimenRequestEnabled(portalCtx.getContainer())) + if (SettingsManager.get().isSpecimenRequestEnabled(portalCtx.getContainer(), portalCtx.getUser())) { if (portalCtx.getContainer().hasPermission(portalCtx.getUser(), RequestSpecimensPermission.class)) items.add(new StudyToolsWebPart.Item("New Request", iconBase + "specimen_request.png", new ActionURL(ShowCreateSpecimenRequestAction.class, portalCtx.getContainer()))); diff --git a/specimen/src/org/labkey/specimen/view/webPart.jsp b/specimen/src/org/labkey/specimen/view/webPart.jsp index 625b8ede82f..de4c00bbcb5 100644 --- a/specimen/src/org/labkey/specimen/view/webPart.jsp +++ b/specimen/src/org/labkey/specimen/view/webPart.jsp @@ -228,7 +228,7 @@ <% - if (SettingsManager.get().isSpecimenRequestEnabled(c)) + if (SettingsManager.get().isSpecimenRequestEnabled(c, getUser())) { %> diff --git a/study/api-src/org/labkey/api/study/QueryHelper.java b/study/api-src/org/labkey/api/study/QueryHelper.java index e9e8c2bff6b..85cd5f6a1aa 100644 --- a/study/api-src/org/labkey/api/study/QueryHelper.java +++ b/study/api-src/org/labkey/api/study/QueryHelper.java @@ -18,7 +18,6 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.cache.CacheLoader; -import org.labkey.api.cache.DbCache; import org.labkey.api.data.Container; import org.labkey.api.data.Filter; import org.labkey.api.data.SimpleFilter; @@ -31,7 +30,6 @@ import org.labkey.api.security.User; import java.util.Collections; -import java.util.Comparator; import java.util.List; public class QueryHelper @@ -85,8 +83,6 @@ else if(null != getTableInfo().getColumn("container")) if (sortString != null) sort = new Sort(sortString); List objs = new TableSelector(getTableInfo(), filter, sort).getArrayList(_objectClass); - if (null == sort) - objs.sort(Comparator.comparingInt(Object::hashCode)); // TODO: temp for comparison purposes -- stable sort if none specified // Make both the objects and the list itself immutable so that we don't end up with a corrupted // version in the cache for (StudyCachable obj : objs) @@ -123,7 +119,6 @@ private K get(final Container c, final Object rowId, final String rowIdColumnNam public K create(User user, K obj) { K ret = Table.insert(user, getTableInfo(), obj); - DbCache.trackRemove(getTableInfo()); clearCache(obj); return ret; } @@ -136,7 +131,6 @@ public K update(User user, K obj) public K update(User user, K obj, Object... pk) { K ret = Table.update(user, getTableInfo(), obj, pk); - DbCache.trackRemove(getTableInfo()); clearCache(obj); return ret; } @@ -144,7 +138,6 @@ public K update(User user, K obj, Object... pk) public void delete(K obj) { Table.delete(getTableInfo(), obj.getPrimaryKey()); - DbCache.trackRemove(getTableInfo()); clearCache(obj); } diff --git a/study/api-src/org/labkey/api/study/StudyCache.java b/study/api-src/org/labkey/api/study/StudyCache.java index 6b46362da88..1e2bc48f87e 100644 --- a/study/api-src/org/labkey/api/study/StudyCache.java +++ b/study/api-src/org/labkey/api/study/StudyCache.java @@ -16,45 +16,30 @@ package org.labkey.api.study; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheLoader; import org.labkey.api.cache.CacheManager; -import org.labkey.api.cache.DbCache; import org.labkey.api.data.Container; import org.labkey.api.data.DatabaseCache; import org.labkey.api.data.TableInfo; import org.labkey.api.util.Path; -import java.util.HashMap; import java.util.Map; -import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; public class StudyCache { - // TODO: Generics! - // TODO: Switch to BlockingCache - private static final Map> CACHES = new HashMap<>(10); + // TODO: Fix generics. Get rid of cache() method and switch to BlockingCaches. Cache (and invalidate) + // a single map per Container for all object types. + private static final Map> CACHES = new ConcurrentHashMap<>(10); - public static DatabaseCache getCache(TableInfo tinfo, boolean create) + public static @NotNull DatabaseCache getCache(TableInfo tinfo) { Path cacheKey = tinfo.getNotificationKey(); assert null != cacheKey : "StudyCache not supported for " + tinfo; - - synchronized(CACHES) - { - DatabaseCache cache = CACHES.get(cacheKey); - - if (null == cache && create) - { - cache = new DatabaseCache(tinfo.getSchema().getScope(), tinfo.getCacheSize(), "StudyCache: " + tinfo.getName()); - CACHES.put(cacheKey, cache); - } - - return cache; - } + return CACHES.computeIfAbsent(cacheKey, key -> new DatabaseCache(tinfo.getSchema().getScope(), tinfo.getCacheSize(), "StudyCache: " + tinfo.getName())); } public static String getCacheName(Container c, @Nullable Object cacheKey) @@ -66,61 +51,29 @@ public static void cache(TableInfo tinfo, Container c, String objectId, StudyCac { if (cachable != null) cachable.lock(); - DbCache.put(tinfo, getCacheName(c, objectId), cachable, CacheManager.HOUR); - DatabaseCache cache = getCache(tinfo, true); - cache.put(getCacheName(c, objectId), cachable, CacheManager.HOUR); - track(tinfo, "Put " + getCacheName(c, objectId)); - } - - private static final Logger LOG = LogManager.getLogger(StudyCache.class); - - public static void track(TableInfo tinfo, String message) - { - if (tinfo.getName().contains("DataSet")) - LOG.info(message); + getCache(tinfo).put(getCacheName(c, objectId), cachable, CacheManager.HOUR); } // TODO: this method is broken/inconsistent -- the cacheKey passed in doesn't match the put() keys public static void uncache(TableInfo tinfo, Container c, Object cacheKey) { - DbCache.remove(tinfo, getCacheName(c, cacheKey)); - DatabaseCache cache = getCache(tinfo, false); - if (null != cache) {cache.remove(getCacheName(c, cacheKey)); cache.clear();} - track(tinfo, "Remove " + getCacheName(c, cacheKey)); + DatabaseCache cache = getCache(tinfo); + cache.remove(getCacheName(c, cacheKey)); + cache.clear(); } public static Object get(TableInfo tinfo, Container c, Object cacheKey, CacheLoader loader) { - // Don't use a BlockingCache as that can cause deadlocks when needing to do a - // load when all other DB connections are in use in threads, including one - // that holds the BlockingCache's lock - DatabaseCache cache = DbCache.getCache(tinfo, true); - Object oldObj = cache.get(getCacheName(c, cacheKey), null, loader); - DatabaseCache cache2 = getCache(tinfo, true); - Object newObj = cache2 != null ? cache2.get(getCacheName(c, cacheKey), null, loader) : null; - - if (!Objects.equals(oldObj, newObj)) - { - DbCache.logUnmatched(); - throw new IllegalStateException(oldObj + " != " + newObj); - } - - return newObj; + return getCache(tinfo).get(getCacheName(c, cacheKey), null, loader); } public static void clearCache(TableInfo tinfo, Container c) { - DbCache.removeUsingPrefix(tinfo, getCacheName(c, null)); - DatabaseCache cache = getCache(tinfo, false); - if (null != cache) - cache.removeUsingFilter(new Cache.StringPrefixFilter(getCacheName(c, null))); - track(tinfo, "Remove using prefix " + getCacheName(c, null)); + getCache(tinfo).removeUsingFilter(new Cache.StringPrefixFilter(getCacheName(c, null))); } public static void clearCache(TableInfo tinfo) { - DatabaseCache cache = getCache(tinfo, false); - if (null != cache) - cache.clear(); + getCache(tinfo).clear(); } } diff --git a/study/src/org/labkey/study/importer/DefaultStudyDesignImporter.java b/study/src/org/labkey/study/importer/DefaultStudyDesignImporter.java index 721fd308c9b..e3468c93f12 100644 --- a/study/src/org/labkey/study/importer/DefaultStudyDesignImporter.java +++ b/study/src/org/labkey/study/importer/DefaultStudyDesignImporter.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.admin.ImportException; import org.labkey.api.admin.InvalidFileException; -import org.labkey.api.cache.DbCache; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.data.AbstractTableInfo; import org.labkey.api.data.Container; @@ -63,9 +62,6 @@ import java.util.SortedSet; import java.util.TreeSet; -/** - * Created by klum on 1/24/14. - */ public class DefaultStudyDesignImporter { /** @@ -73,11 +69,11 @@ public class DefaultStudyDesignImporter */ protected void deleteData(Container container, TableInfo tableInfo) throws ImportException { - try { + try + { if (tableInfo instanceof FilteredTable) { Table.delete(((FilteredTable)tableInfo).getRealTable(), SimpleFilter.createContainerFilter(container)); - if (tableInfo.getName().equals("AssaySpecimen")) DbCache.trackRemove(((FilteredTable)tableInfo).getRealTable()); } } catch (RuntimeSQLException e) diff --git a/study/src/org/labkey/study/model/StudyManager.java b/study/src/org/labkey/study/model/StudyManager.java index 2f4cf753221..73e16d8bc44 100644 --- a/study/src/org/labkey/study/model/StudyManager.java +++ b/study/src/org/labkey/study/model/StudyManager.java @@ -38,7 +38,6 @@ import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheLoader; import org.labkey.api.cache.CacheManager; -import org.labkey.api.cache.DbCache; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.collections.LabKeyCollectors; @@ -209,7 +208,6 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; @@ -218,7 +216,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.WeakHashMap; -import java.util.stream.Collectors; import static org.labkey.api.action.SpringActionController.ERROR_MSG; import static org.labkey.study.query.StudyQuerySchema.PERSONNEL_TABLE_NAME; @@ -407,18 +404,10 @@ private class DatasetHelper () -> StudySchema.getInstance().getTableInfoDataset(), DatasetDefinition.class) { - @Override - public void clearCache(Container c) - { - super.clearCache(c); - StudyCache.track(getTableInfo(), "Clear container " + c); - } - @Override public void clearCache(DatasetDefinition obj) { super.clearCache(obj.getContainer()); - StudyCache.track(getTableInfo(), "Clear container " + obj.getContainer() + " for dataset " + obj); } }; @@ -516,20 +505,7 @@ private DatasetDefinition toSharedInstance(DatasetDefinition dsIn) private static Object getCached(TableInfo tinfo, Container c, Object cacheKey) { - Object oldObj = DbCache.get(tinfo, StudyCache.getCacheName(c, cacheKey)); - DatabaseCache cache = StudyCache.getCache(tinfo, false); - Object newObj = cache != null ? cache.get(StudyCache.getCacheName(c, cacheKey)) : null; - - if (!Objects.equals(oldObj, newObj)) - { - if (newObj instanceof List || oldObj instanceof List) - { - DbCache.logUnmatched(); - throw new IllegalStateException(oldObj + " != " + newObj); - } - } - - return newObj; + return StudyCache.getCache(tinfo).get(StudyCache.getCacheName(c, cacheKey)); } } @@ -1735,7 +1711,6 @@ public void deleteVisits(StudyImpl study, Collection visits, User use try { Table.delete(schema.getTableInfoVisit(), new Object[]{visitStudy.getContainer(), visit.getRowId()}); - DbCache.trackRemove(schema.getTableInfoVisit()); } finally { @@ -1768,7 +1743,6 @@ public void updateCohort(User user, CohortImpl cohort) public void updateParticipant(User user, Participant participant) { Table.update(user, SCHEMA.getTableInfoParticipant(), participant, new Object[]{participant.getContainer().getId(), participant.getParticipantId()}); - DbCache.trackRemove(SCHEMA.getTableInfoParticipant()); _participantCache.remove(participant.getContainer()); } @@ -1894,8 +1868,6 @@ public void clearParticipantVisitCaches(Study study) if (!study.equals(visitStudy)) _visitHelper.clearCache(visitStudy.getContainer()); - DbCache.clear(StudySchema.getInstance().getTableInfoParticipant()); - DbCache.trackRemove(StudySchema.getInstance().getTableInfoParticipant()); _participantCache.remove(study.getContainer()); for (StudyImpl substudy : StudyManager.getInstance().getAncillaryStudies(study.getContainer())) clearParticipantVisitCaches(substudy); @@ -2734,7 +2706,6 @@ public void deleteDataset(StudyImpl study, User user, DatasetDefinition ds, bool unindexDataset(ds); } - /** delete a dataset type and data * does not clear typeURI as we're about to delete the dataset */ @@ -2776,12 +2747,9 @@ public void clearCaches(Container c, boolean unmaterializeDatasets) for (DatasetDefinition def : getDatasetDefinitions(study)) uncache(def); // Aggressive, but datasets are cached with container objects that might go stale, for example, when moving a - // folder tree to another parent the datasets in subfolders will be left with invalid paths. See FolderTest. + // folder tree to another parent, the datasets in subfolders will be left with invalid paths. See FolderTest. _datasetHelper.clearCache(); _cohortHelper.clearCache(c); - - DbCache.clear(StudySchema.getInstance().getTableInfoParticipant()); - DbCache.trackRemove(StudySchema.getInstance().getTableInfoParticipant()); _participantCache.remove(c); for (StudyImpl substudy : StudyManager.getInstance().getAncillaryStudies(c)) @@ -2835,7 +2803,6 @@ public void deleteAllStudyData(Container c, User user) Table.delete(SCHEMA.getTableInfoAssaySpecimenVisit(), containerFilter); assert deletedTables.add(SCHEMA.getTableInfoAssaySpecimenVisit()); Table.delete(_assaySpecimenHelper.getTableInfo(), containerFilter); - DbCache.trackRemove(_assaySpecimenHelper.getTableInfo()); _assaySpecimenHelper.clearCache(c); assert deletedTables.add(_assaySpecimenHelper.getTableInfo()); @@ -2847,15 +2814,12 @@ public void deleteAllStudyData(Container c, User user) Table.delete(StudySchema.getInstance().getTableInfoUploadLog(), containerFilter); assert deletedTables.add(StudySchema.getInstance().getTableInfoUploadLog()); Table.delete(_datasetHelper.getTableInfo(), containerFilter); - DbCache.trackRemove(_datasetHelper.getTableInfo()); _datasetHelper.clearCache(c); assert deletedTables.add(_datasetHelper.getTableInfo()); Table.delete(_visitHelper.getTableInfo(), containerFilter); - DbCache.trackRemove(_visitHelper.getTableInfo()); _visitHelper.clearCache(c); assert deletedTables.add(_visitHelper.getTableInfo()); Table.delete(_studyHelper.getTableInfo(), containerFilter); - DbCache.trackRemove(_studyHelper.getTableInfo()); _studyHelper.clearCache(c); assert deletedTables.add(_studyHelper.getTableInfo()); @@ -2878,11 +2842,9 @@ public void deleteAllStudyData(Container c, User user) Table.delete(StudySchema.getInstance().getTableInfoVisitAliases(), containerFilter); assert deletedTables.add(StudySchema.getInstance().getTableInfoVisitAliases()); Table.delete(SCHEMA.getTableInfoParticipant(), containerFilter); - DbCache.trackRemove(SCHEMA.getTableInfoParticipant()); _participantCache.remove(c); assert deletedTables.add(SCHEMA.getTableInfoParticipant()); Table.delete(_cohortHelper.getTableInfo(), containerFilter); - DbCache.trackRemove(_cohortHelper.getTableInfo()); _cohortHelper.clearCache(c); assert deletedTables.add(StudySchema.getInstance().getTableInfoCohort()); Table.delete(StudySchema.getInstance().getTableInfoParticipantView(), containerFilter); @@ -4148,32 +4110,11 @@ private String getParticipantCacheKey(Container container) /** non-permission checking, non-recursive */ private Map getParticipantMap(Study study) { - Map participantMap = (Map) DbCache.get(StudySchema.getInstance().getTableInfoParticipant(), getParticipantCacheKey(study.getContainer())); - if (participantMap == null) - { - SimpleFilter filter = SimpleFilter.createContainerFilter(study.getContainer()); - ArrayList participants = new TableSelector(StudySchema.getInstance().getTableInfoParticipant(), - filter, new Sort("ParticipantId")).getArrayList(Participant.class); - participantMap = new LinkedHashMap<>(); - for (Participant participant : participants) - participantMap.put(participant.getParticipantId(), participant); - participantMap = Collections.unmodifiableMap(participantMap); - DbCache.put(StudySchema.getInstance().getTableInfoParticipant(), getParticipantCacheKey(study.getContainer()), participantMap, CacheManager.HOUR); - } - Map participantMapNew = _participantCache.get(study.getContainer()); - - if (!Objects.equals(participantMap, participantMapNew)) - { - DbCache.logUnmatched(); - throw new IllegalStateException(participantMap + " != " + participantMapNew); - } - - return participantMapNew; + return _participantCache.get(study.getContainer()); } public void clearParticipantCache(Container container) { - DbCache.remove(StudySchema.getInstance().getTableInfoParticipant(), getParticipantCacheKey(container)); _participantCache.remove(container); } diff --git a/study/src/org/labkey/study/model/TreatmentManager.java b/study/src/org/labkey/study/model/TreatmentManager.java index a8d039ffc06..6d417f2b758 100644 --- a/study/src/org/labkey/study/model/TreatmentManager.java +++ b/study/src/org/labkey/study/model/TreatmentManager.java @@ -62,7 +62,7 @@ */ public class TreatmentManager { - private static TreatmentManager _instance = new TreatmentManager(); + private static final TreatmentManager _instance = new TreatmentManager(); private TreatmentManager() { @@ -171,9 +171,7 @@ public List getFilteredTreatments(Container container, User user, TableInfo ti = QueryService.get().getUserSchema(user, container, StudyQuerySchema.SCHEMA_NAME).getTable(StudyQuerySchema.TREATMENT_TABLE_NAME); //Using a user schema so containerFilter will be created for us later (so don't need SimpleFilter.createContainerFilter) - SimpleFilter filter = new SimpleFilter(); - if (filterRowIds != null && !filterRowIds.isEmpty()) - filter.addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); + SimpleFilter filter = new SimpleFilter().addCondition(FieldKey.fromParts("RowId"), filterRowIds, CompareType.NOT_IN); return new TableSelector(ti, filter, new Sort("RowId")).getArrayList(TreatmentImpl.class); } diff --git a/study/src/org/labkey/study/query/StudyPropertiesTable.java b/study/src/org/labkey/study/query/StudyPropertiesTable.java index f77763fb23c..31e41f6b0f2 100644 --- a/study/src/org/labkey/study/query/StudyPropertiesTable.java +++ b/study/src/org/labkey/study/query/StudyPropertiesTable.java @@ -19,7 +19,6 @@ import org.labkey.api.action.SpringActionController; import org.labkey.api.data.AbstractTableInfo; import org.labkey.api.data.BaseColumnInfo; -import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; import org.labkey.api.data.ContainerForeignKey; @@ -53,15 +52,10 @@ import java.util.ArrayList; import java.util.List; -/** - * User: jgarms - * Date: Aug 7, 2008 - * Time: 4:23:44 PM - */ public class StudyPropertiesTable extends BaseStudyTable { private Domain _domain; - private List _visibleColumns = new ArrayList<>(); + private final List _visibleColumns = new ArrayList<>(); public StudyPropertiesTable(StudyQuerySchema schema, ContainerFilter cf) { @@ -144,9 +138,9 @@ public TableInfo getLookupTableInfo() } else { - for (ColumnInfo extraColumn : _domain.getColumns(this, lsidColumn, c, schema.getUser())) + for (BaseColumnInfo extraColumn : _domain.getColumns(this, lsidColumn, c, schema.getUser())) { - safeAddColumn( (BaseColumnInfo) extraColumn); + safeAddColumn(extraColumn); _visibleColumns.add(FieldKey.fromParts(extraColumn.getName())); } } diff --git a/study/src/org/labkey/study/query/StudyPropertiesUpdateService.java b/study/src/org/labkey/study/query/StudyPropertiesUpdateService.java index d3257cc637f..5f2327c9a17 100644 --- a/study/src/org/labkey/study/query/StudyPropertiesUpdateService.java +++ b/study/src/org/labkey/study/query/StudyPropertiesUpdateService.java @@ -16,7 +16,6 @@ package org.labkey.study.query; import org.jetbrains.annotations.Nullable; -import org.labkey.api.cache.DbCache; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; @@ -137,7 +136,6 @@ else if (c.isUserEditable()) if (!updateRow.isEmpty()) { Table.update(user, table.getRealTable(), updateRow, study.getContainer().getId()); - DbCache.trackRemove(table.getRealTable()); } StudyManager.getInstance().clearCaches(container, false); From f66f7ba69830cbd369003936ab77b3e1b684416e Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Thu, 23 May 2024 17:14:00 -0700 Subject: [PATCH 2/3] More cleanup --- specimen/src/org/labkey/specimen/SpecimenModule.java | 8 -------- .../src/org/labkey/specimen/settings/SettingsManager.java | 1 - .../labkey/specimen/writer/SpecimenSettingsWriter.java | 8 ++------ 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/specimen/src/org/labkey/specimen/SpecimenModule.java b/specimen/src/org/labkey/specimen/SpecimenModule.java index e74bb9f6a1c..13b7115ae73 100644 --- a/specimen/src/org/labkey/specimen/SpecimenModule.java +++ b/specimen/src/org/labkey/specimen/SpecimenModule.java @@ -95,7 +95,6 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -317,13 +316,6 @@ protected void startupAfterSpringConfig(ModuleContext moduleContext) } } - @Override - @NotNull - public Collection getSummary(Container c) - { - return Collections.emptyList(); - } - @Override @NotNull public Set getUnitTests() diff --git a/specimen/src/org/labkey/specimen/settings/SettingsManager.java b/specimen/src/org/labkey/specimen/settings/SettingsManager.java index 6806693e792..beb6c64f1e5 100644 --- a/specimen/src/org/labkey/specimen/settings/SettingsManager.java +++ b/specimen/src/org/labkey/specimen/settings/SettingsManager.java @@ -5,7 +5,6 @@ import org.labkey.api.data.PropertyManager; import org.labkey.api.security.User; import org.labkey.api.security.UserManager; -import org.labkey.api.specimen.SpecimenSchema; import org.labkey.api.specimen.settings.DisplaySettings; import org.labkey.api.specimen.settings.RepositorySettings; import org.labkey.api.specimen.settings.StatusSettings; diff --git a/specimen/src/org/labkey/specimen/writer/SpecimenSettingsWriter.java b/specimen/src/org/labkey/specimen/writer/SpecimenSettingsWriter.java index ea6a07c5b5d..998981da015 100644 --- a/specimen/src/org/labkey/specimen/writer/SpecimenSettingsWriter.java +++ b/specimen/src/org/labkey/specimen/writer/SpecimenSettingsWriter.java @@ -49,10 +49,6 @@ import java.util.Collections; import java.util.List; -/** - * User: kevink - * Date: 6/13/13 - */ public class SpecimenSettingsWriter extends AbstractSpecimenWriter { private static final String DEFAULT_SETTINGS_FILE = "specimen_settings.xml"; @@ -119,7 +115,7 @@ private void writeLocationTypes(SpecimenSettingsType specimenSettingsType, Study private void writeSpecimenGroupings(SpecimenSettingsType specimenSettingsType, RepositorySettings repositorySettings) { ArrayList groupings = repositorySettings.getSpecimenWebPartGroupings(); - if (groupings.size() > 0) + if (!groupings.isEmpty()) { SpecimenSettingsType.WebPartGroupings xmlWebPartGroupings = specimenSettingsType.addNewWebPartGroupings(); for (String[] grouping : groupings) @@ -134,7 +130,7 @@ private void writeRequestStatuses(SpecimenSettingsType specimenSettingsType, Stu { SpecimenSettingsType.RequestStatuses xmlRequestStatuses = null; List statuses = SpecimenRequestManager.get().getRequestStatuses(study.getContainer(), ctx.getUser()); - if (statuses.size() > 0) + if (!statuses.isEmpty()) { for (SpecimenRequestStatus status : statuses) { From 71b90e5a9831ac438c11bde51aaf1b75e3f3b205 Mon Sep 17 00:00:00 2001 From: Adam Rauch Date: Fri, 24 May 2024 09:39:44 -0700 Subject: [PATCH 3/3] Tiny clean up to DatasetHelper --- .../org/labkey/study/model/StudyManager.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/study/src/org/labkey/study/model/StudyManager.java b/study/src/org/labkey/study/model/StudyManager.java index b0480406df9..6894384c472 100644 --- a/study/src/org/labkey/study/model/StudyManager.java +++ b/study/src/org/labkey/study/model/StudyManager.java @@ -365,7 +365,7 @@ public void clearCache(StudyImpl obj) Container sharedContainer = ContainerManager.getSharedContainer(); assert key != sharedContainer; - List defs = _datasetHelper.get(key); + List defs = _datasetHelper.getList(key); if (defs == null) return Collections.emptySet(); @@ -452,21 +452,16 @@ public DatasetDefinition update(User user, DatasetDefinition obj, Object... pk) return helper.update(user, obj, pk); } - public List get(Container c) + public List getList(Container c) { return toSharedInstance(helper.getList(c)); } - public List get(Container c, SimpleFilter filter) + public List getList(Container c, SimpleFilter filter) { return toSharedInstance(helper.getList(c, filter)); } - public List get(Container c, @Nullable SimpleFilter filterArg, @Nullable String sortString) - { - return toSharedInstance(helper.getList(c, filterArg, sortString)); - } - public DatasetDefinition get(Container c, int rowId) { return toSharedInstance(helper.get(c, rowId, "DatasetId")); @@ -2341,7 +2336,7 @@ public List getDatasetDefinitionsLocal(Study study, @Nullable } // Make a copy (it's immutable) so that we can sort it. See issue 17875 - return new ArrayList<>(_datasetHelper.get(study.getContainer(), filter, null)); + return new ArrayList<>(_datasetHelper.getList(study.getContainer(), filter)); } @@ -2390,7 +2385,7 @@ public DatasetDefinition getDatasetDefinitionByLabel(Study s, String label) SimpleFilter filter = SimpleFilter.createContainerFilter(s.getContainer()); filter.addWhereClause("LOWER(Label) = ?", new Object[]{label.toLowerCase()}, FieldKey.fromParts("Label")); - List defs = _datasetHelper.get(s.getContainer(), filter); + List defs = _datasetHelper.getList(s.getContainer(), filter); if (defs.size() == 1) return defs.get(0); @@ -2404,7 +2399,7 @@ public DatasetDefinition getDatasetDefinitionByEntityId(Study s, String entityId SimpleFilter filter = SimpleFilter.createContainerFilter(s.getContainer()); filter.addCondition(FieldKey.fromParts("EntityId"), entityId); - List defs = _datasetHelper.get(s.getContainer(), filter); + List defs = _datasetHelper.getList(s.getContainer(), filter); if (defs.size() == 1) return defs.get(0); @@ -2418,7 +2413,7 @@ public DatasetDefinition getDatasetDefinitionByName(Study s, String name) SimpleFilter filter = SimpleFilter.createContainerFilter(s.getContainer()); filter.addWhereClause("LOWER(Name) = LOWER(?)", new Object[]{name}, FieldKey.fromParts("Name")); - List defs = _datasetHelper.get(s.getContainer(), filter); + List defs = _datasetHelper.getList(s.getContainer(), filter); if (defs.size() == 1) return defs.get(0); @@ -4768,7 +4763,7 @@ private List getDatasetsForCategory(ViewCategory category) { SimpleFilter filter = SimpleFilter.createContainerFilter(study.getContainer()); filter.addCondition(FieldKey.fromParts("CategoryId"), category.getRowId()); - return _instance._datasetHelper.get(study.getContainer(), filter); + return _instance._datasetHelper.getList(study.getContainer(), filter); } }