You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/11/03 15:09:56 UTC
(commons-jcs) branch master updated (902fed0b -> 4640fe5e)
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git
from 902fed0b Merge pull request #183 from apache/dependabot/github_actions/github/codeql-action-2.22.5
new 159accd3 Normalize test method names
new 4640fe5e Sort members
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../src/main/java/org/apache/commons/jcs3/JCS.java | 160 +-
.../commons/jcs3/access/AbstractCacheAccess.java | 112 +-
.../apache/commons/jcs3/access/CacheAccess.java | 152 +-
.../commons/jcs3/access/GroupCacheAccess.java | 86 +-
.../commons/jcs3/access/behavior/ICacheAccess.java | 94 +-
.../access/behavior/ICacheAccessManagement.java | 74 +-
.../jcs3/access/behavior/IGroupCacheAccess.java | 30 +-
.../jcs3/access/exception/CacheException.java | 16 +-
.../commons/jcs3/admin/CacheElementInfo.java | 26 +-
.../apache/commons/jcs3/admin/CacheRegionInfo.java | 46 +-
.../jcs3/admin/CountingOnlyOutputStream.java | 20 +-
.../apache/commons/jcs3/admin/JCSAdminBean.java | 206 +--
.../org/apache/commons/jcs3/admin/JCSJMXBean.java | 28 +-
.../jcs3/auxiliary/AbstractAuxiliaryCache.java | 160 +-
.../AbstractAuxiliaryCacheAttributes.java | 68 +-
.../AbstractAuxiliaryCacheEventLogging.java | 214 +--
.../auxiliary/AbstractAuxiliaryCacheMonitor.java | 74 +-
.../commons/jcs3/auxiliary/AuxiliaryCache.java | 22 +-
.../jcs3/auxiliary/AuxiliaryCacheAttributes.java | 42 +-
.../jcs3/auxiliary/AuxiliaryCacheFactory.java | 22 +-
.../jcs3/auxiliary/disk/AbstractDiskCache.java | 878 +++++-----
.../disk/AbstractDiskCacheAttributes.java | 154 +-
.../jcs3/auxiliary/disk/PurgatoryElement.java | 86 +-
.../disk/behavior/IDiskCacheAttributes.java | 58 +-
.../jcs3/auxiliary/disk/block/BlockDisk.java | 348 ++--
.../jcs3/auxiliary/disk/block/BlockDiskCache.java | 588 +++----
.../disk/block/BlockDiskCacheAttributes.java | 44 +-
.../disk/block/BlockDiskElementDescriptor.java | 46 +-
.../auxiliary/disk/block/BlockDiskKeyStore.java | 6 +-
.../jcs3/auxiliary/disk/indexed/IndexedDisk.java | 224 +--
.../auxiliary/disk/indexed/IndexedDiskCache.java | 1830 +++++++++----------
.../disk/indexed/IndexedDiskCacheAttributes.java | 66 +-
.../disk/indexed/IndexedDiskElementDescriptor.java | 64 +-
.../jcs3/auxiliary/disk/jdbc/JDBCDiskCache.java | 594 +++----
.../disk/jdbc/JDBCDiskCacheAttributes.java | 212 +--
.../auxiliary/disk/jdbc/JDBCDiskCacheFactory.java | 140 +-
.../jcs3/auxiliary/disk/jdbc/ShrinkerThread.java | 50 +-
.../jcs3/auxiliary/disk/jdbc/TableState.java | 20 +-
.../disk/jdbc/dsfactory/DataSourceFactory.java | 34 +-
.../disk/jdbc/dsfactory/JndiDataSourceFactory.java | 54 +-
.../dsfactory/SharedPoolDataSourceFactory.java | 120 +-
.../auxiliary/disk/jdbc/mysql/MySQLDiskCache.java | 70 +-
.../disk/jdbc/mysql/MySQLDiskCacheAttributes.java | 32 +-
.../disk/jdbc/mysql/MySQLDiskCacheFactory.java | 68 +-
.../disk/jdbc/mysql/MySQLTableOptimizer.java | 74 +-
.../jcs3/auxiliary/lateral/LateralCache.java | 354 ++--
.../auxiliary/lateral/LateralCacheAttributes.java | 126 +-
.../jcs3/auxiliary/lateral/LateralCacheNoWait.java | 346 ++--
.../lateral/LateralCacheNoWaitFacade.java | 328 ++--
.../lateral/LateralElementDescriptor.java | 22 +-
.../lateral/behavior/ILateralCacheAttributes.java | 108 +-
.../lateral/behavior/ILateralCacheListener.java | 18 +-
.../lateral/socket/tcp/LateralTCPCacheFactory.java | 260 +--
.../socket/tcp/LateralTCPDiscoveryListener.java | 260 +--
.../lateral/socket/tcp/LateralTCPListener.java | 640 +++----
.../lateral/socket/tcp/LateralTCPSender.java | 28 +-
.../lateral/socket/tcp/LateralTCPService.java | 220 +--
.../socket/tcp/TCPLateralCacheAttributes.java | 258 +--
.../tcp/behavior/ITCPLateralCacheAttributes.java | 212 +--
.../remote/AbstractRemoteAuxiliaryCache.java | 560 +++---
.../remote/AbstractRemoteCacheListener.java | 100 +-
.../remote/AbstractRemoteCacheNoWaitFacade.java | 242 +--
.../remote/CommonRemoteCacheAttributes.java | 150 +-
.../commons/jcs3/auxiliary/remote/RemoteCache.java | 94 +-
.../auxiliary/remote/RemoteCacheAttributes.java | 124 +-
.../jcs3/auxiliary/remote/RemoteCacheFactory.java | 54 +-
.../jcs3/auxiliary/remote/RemoteCacheManager.java | 190 +-
.../jcs3/auxiliary/remote/RemoteCacheNoWait.java | 326 ++--
.../auxiliary/remote/RemoteCacheNoWaitFacade.java | 70 +-
.../jcs3/auxiliary/remote/RemoteLocation.java | 72 +-
.../commons/jcs3/auxiliary/remote/RemoteUtils.java | 174 +-
.../behavior/ICommonRemoteCacheAttributes.java | 110 +-
.../remote/behavior/IRemoteCacheAttributes.java | 108 +-
.../remote/behavior/IRemoteCacheClient.java | 16 +-
.../remote/behavior/IRemoteCacheListener.java | 62 +-
.../remote/http/client/AbstractHttpClient.java | 30 +-
.../remote/http/client/RemoteHttpCache.java | 34 +-
.../http/client/RemoteHttpCacheAttributes.java | 106 +-
.../remote/http/client/RemoteHttpCacheClient.java | 266 +--
.../http/client/RemoteHttpCacheDispatcher.java | 58 +-
.../remote/http/client/RemoteHttpCacheFactory.java | 24 +-
.../remote/http/client/RemoteHttpCacheMonitor.java | 32 +-
.../http/server/AbstractRemoteCacheService.java | 448 ++---
.../server/RemoteHttpCacheServerAttributes.java | 26 +-
.../remote/http/server/RemoteHttpCacheService.java | 94 +-
.../remote/http/server/RemoteHttpCacheServlet.java | 242 +--
.../auxiliary/remote/server/RemoteCacheServer.java | 1278 +++++++-------
.../remote/server/RemoteCacheServerAttributes.java | 80 +-
.../remote/server/RemoteCacheServerFactory.java | 394 ++---
.../remote/server/RemoteCacheStartupServlet.java | 148 +-
.../TimeoutConfigurableRMISocketFactory.java | 12 +-
.../behavior/IRemoteCacheServerAttributes.java | 56 +-
.../remote/util/RemoteCacheRequestFactory.java | 94 +-
.../auxiliary/remote/value/RemoteCacheRequest.java | 84 +-
.../remote/value/RemoteCacheResponse.java | 28 +-
.../jcs3/engine/AbstractCacheEventQueue.java | 440 ++---
.../apache/commons/jcs3/engine/CacheAdaptor.java | 32 +-
.../apache/commons/jcs3/engine/CacheElement.java | 90 +-
.../jcs3/engine/CacheElementSerialized.java | 88 +-
.../jcs3/engine/CacheEventQueueFactory.java | 32 +-
.../org/apache/commons/jcs3/engine/CacheInfo.java | 10 +-
.../commons/jcs3/engine/CacheWatchRepairable.java | 84 +-
.../jcs3/engine/CompositeCacheAttributes.java | 254 +--
.../commons/jcs3/engine/ElementAttributes.java | 292 ++--
.../commons/jcs3/engine/PooledCacheEventQueue.java | 76 +-
.../commons/jcs3/engine/ZombieCacheService.java | 64 +-
.../jcs3/engine/ZombieCacheServiceNonLocal.java | 238 +--
.../commons/jcs3/engine/ZombieCacheWatch.java | 12 +-
.../commons/jcs3/engine/behavior/ICache.java | 68 +-
.../jcs3/engine/behavior/ICacheElement.java | 14 +-
.../jcs3/engine/behavior/ICacheEventQueue.java | 66 +-
.../jcs3/engine/behavior/ICacheListener.java | 34 +-
.../jcs3/engine/behavior/ICacheObserver.java | 26 +-
.../jcs3/engine/behavior/ICacheService.java | 46 +-
.../engine/behavior/ICacheServiceNonLocal.java | 70 +-
.../engine/behavior/ICompositeCacheAttributes.java | 192 +-
.../engine/behavior/ICompositeCacheManager.java | 14 +-
.../jcs3/engine/behavior/IElementAttributes.java | 172 +-
.../jcs3/engine/behavior/IElementSerializer.java | 238 +--
.../jcs3/engine/behavior/IShutdownObservable.java | 10 +-
.../jcs3/engine/control/CompositeCache.java | 1838 ++++++++++----------
.../engine/control/CompositeCacheConfigurator.java | 508 +++---
.../jcs3/engine/control/CompositeCacheManager.java | 778 ++++-----
.../engine/control/event/ElementEventQueue.java | 28 +-
.../commons/jcs3/engine/logging/CacheEvent.java | 72 +-
.../jcs3/engine/logging/behavior/ICacheEvent.java | 34 +-
.../engine/logging/behavior/ICacheEventLogger.java | 14 +-
.../AbstractDoubleLinkedListMemoryCache.java | 372 ++--
.../jcs3/engine/memory/AbstractMemoryCache.java | 432 ++---
.../jcs3/engine/memory/behavior/IMemoryCache.java | 138 +-
.../jcs3/engine/memory/fifo/FIFOMemoryCache.java | 22 +-
.../jcs3/engine/memory/lru/LHMLRUMemoryCache.java | 186 +-
.../jcs3/engine/memory/lru/LRUMemoryCache.java | 22 +-
.../jcs3/engine/memory/mru/MRUMemoryCache.java | 22 +-
.../memory/soft/SoftReferenceMemoryCache.java | 90 +-
.../commons/jcs3/engine/stats/CacheStats.java | 28 +-
.../commons/jcs3/engine/stats/StatElement.java | 32 +-
.../apache/commons/jcs3/engine/stats/Stats.java | 12 +-
.../jcs3/engine/stats/behavior/ICacheStats.java | 18 +-
.../jcs3/engine/stats/behavior/IStatElement.java | 22 +-
.../commons/jcs3/engine/stats/behavior/IStats.java | 12 +-
.../jcs3/io/ObjectInputStreamClassLoaderAware.java | 82 +-
.../org/apache/commons/jcs3/log/JulLogAdapter.java | 184 +-
.../org/apache/commons/jcs3/log/JulLogFactory.java | 40 +-
.../main/java/org/apache/commons/jcs3/log/Log.java | 48 +-
.../org/apache/commons/jcs3/log/Log4j2Factory.java | 40 +-
.../apache/commons/jcs3/log/Log4j2LogAdapter.java | 124 +-
.../org/apache/commons/jcs3/log/LogFactory.java | 24 +-
.../org/apache/commons/jcs3/log/LogManager.java | 76 +-
.../apache/commons/jcs3/log/MessageFormatter.java | 34 +-
.../commons/jcs3/utils/access/JCSWorkerHelper.java | 22 +-
.../commons/jcs3/utils/config/OptionConverter.java | 290 +--
.../commons/jcs3/utils/config/PropertySetter.java | 220 +--
.../jcs3/utils/discovery/DiscoveredService.java | 96 +-
.../utils/discovery/UDPDiscoveryAttributes.java | 156 +-
.../jcs3/utils/discovery/UDPDiscoveryManager.java | 18 +-
.../jcs3/utils/discovery/UDPDiscoveryMessage.java | 66 +-
.../jcs3/utils/discovery/UDPDiscoveryReceiver.java | 200 +--
.../jcs3/utils/discovery/UDPDiscoverySender.java | 146 +-
.../jcs3/utils/discovery/UDPDiscoveryService.java | 338 ++--
.../utils/serialization/CompressingSerializer.java | 30 +-
.../utils/serialization/EncryptingSerializer.java | 152 +-
.../serialization/SerializationConversionUtil.java | 82 +-
.../utils/serialization/StandardSerializer.java | 42 +-
.../utils/servlet/JCSServletContextListener.java | 20 +-
.../commons/jcs3/utils/struct/AbstractLRUMap.java | 280 +--
.../jcs3/utils/struct/DoubleLinkedList.java | 118 +-
.../jcs3/utils/struct/LRUElementDescriptor.java | 12 +-
.../jcs3/utils/threadpool/DaemonThreadFactory.java | 2 +-
.../jcs3/utils/threadpool/PoolConfiguration.java | 162 +-
.../jcs3/utils/threadpool/ThreadPoolManager.java | 238 +--
.../commons/jcs3/utils/zip/CompressionUtil.java | 114 +-
.../jcs3/JCSConcurrentCacheAccessUnitTest.java | 80 +-
.../jcs3/JCSRemovalSimpleConcurrentTest.java | 82 +-
.../org/apache/commons/jcs3/JCSThrashTest.java | 248 +--
.../java/org/apache/commons/jcs3/JCSUnitTest.java | 32 +-
.../jcs3/JCSvsHashtablePerformanceTest.java | 50 +-
.../org/apache/commons/jcs3/RemovalTestUtil.java | 56 +-
.../commons/jcs3/TestLogConfigurationUtil.java | 50 +-
.../apache/commons/jcs3/TestTCPLateralCache.java | 92 +-
.../commons/jcs3/access/CacheAccessUnitTest.java | 340 ++--
.../jcs3/access/GroupCacheAccessUnitTest.java | 198 +--
.../commons/jcs3/access/TestCacheAccess.java | 974 +++++------
.../commons/jcs3/admin/AdminBeanUnitTest.java | 84 +-
.../commons/jcs3/admin/CountingStreamUnitTest.java | 32 +-
.../AuxiliaryCacheConfiguratorUnitTest.java | 40 +-
.../commons/jcs3/auxiliary/MockAuxiliaryCache.java | 120 +-
.../jcs3/auxiliary/MockCacheEventLogger.java | 30 +-
.../auxiliary/disk/AbstractDiskCacheUnitTest.java | 270 +--
.../auxiliary/disk/PurgatoryElementUnitTest.java | 22 +-
.../disk/block/AbstractBlockDiskCacheUnitTest.java | 552 +++---
.../block/BlockDiskCacheConcurrentUnitTest.java | 136 +-
.../disk/block/BlockDiskCacheKeyStoreUnitTest.java | 96 +-
.../BlockDiskCacheRandomConcurrentTestUtil.java | 12 +-
...BlockDiskCacheSameRegionConcurrentUnitTest.java | 88 +-
.../disk/block/BlockDiskCacheSteadyLoadTest.java | 28 +-
.../auxiliary/disk/block/BlockDiskUnitTest.java | 242 +--
.../block/HugeQuantityBlockDiskCacheLoadTest.java | 28 +-
.../indexed/AbstractIndexDiskCacheUnitTest.java | 1072 ++++++------
.../auxiliary/disk/indexed/DiskTestObjectUtil.java | 102 +-
.../indexed/HugeQuantityIndDiskCacheLoadTest.java | 30 +-
.../IndexedDiskCacheConcurrentUnitTest.java | 122 +-
.../IndexedDiskCacheDefragPerformanceTest.java | 96 +-
.../indexed/IndexedDiskCacheKeyStoreUnitTest.java | 78 +-
.../indexed/IndexedDiskCacheNoMemoryUnitTest.java | 86 +-
...dexedDiskCacheSameRegionConcurrentUnitTest.java | 154 +-
.../indexed/IndexedDiskCacheSteadyLoadTest.java | 28 +-
.../auxiliary/disk/indexed/LRUMapSizeVsCount.java | 30 +-
.../jcs3/auxiliary/disk/jdbc/HsqlSetupUtil.java | 26 +-
.../disk/jdbc/JDBCDataSourceFactoryUnitTest.java | 170 +-
.../disk/jdbc/JDBCDiskCacheSharedPoolUnitTest.java | 50 +-
.../disk/jdbc/JDBCDiskCacheShrinkUnitTest.java | 62 +-
.../auxiliary/disk/jdbc/JDBCDiskCacheUnitTest.java | 46 +-
.../jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java | 102 +-
.../mysql/MySQLDiskCacheHsqlBackedUnitTest.java | 50 +-
.../mysql/util/ScheduleParserUtilUnitTest.java | 90 +-
.../lateral/LateralCacheNoWaitFacadeUnitTest.java | 34 +-
.../tcp/LateralTCPConcurrentRandomTestUtil.java | 22 +-
.../tcp/LateralTCPDiscoveryListenerUnitTest.java | 148 +-
.../LateralTCPFilterRemoveHashCodeUnitTest.java | 44 +-
.../tcp/LateralTCPIssueRemoveOnPutUnitTest.java | 130 +-
.../lateral/socket/tcp/TestTCPLateralUnitTest.java | 226 +--
.../auxiliary/remote/MockRemoteCacheClient.java | 146 +-
.../auxiliary/remote/MockRemoteCacheListener.java | 26 +-
.../auxiliary/remote/MockRemoteCacheService.java | 136 +-
.../auxiliary/remote/RemoteCacheClientTester.java | 174 +-
.../remote/RemoteCacheNoWaitUnitTest.java | 74 +-
.../jcs3/auxiliary/remote/RemoteCacheUnitTest.java | 120 +-
.../jcs3/auxiliary/remote/TestRemoteCache.java | 46 +-
.../auxiliary/remote/TestRemoteCacheFactory.java | 64 +-
.../remote/ZombieRemoteCacheServiceUnitTest.java | 50 +-
.../http/client/RemoteHttpCacheClientUnitTest.java | 68 +-
.../server/RemoteHttpCacheServiceUnitTest.java | 34 +-
.../server/RemoteHttpCacheServletUnitTest.java | 46 +-
.../remote/server/MockRMISocketFactory.java | 34 +-
.../RemoteCacheServerAttributesUnitTest.java | 16 +-
.../server/RemoteCacheServerFactoryUnitTest.java | 102 +-
.../remote/server/RemoteCacheServerUnitTest.java | 274 +--
.../util/RemoteCacheRequestFactoryUnitTest.java | 42 +-
.../engine/CacheEventQueueFactoryUnitTest.java | 12 +-
.../jcs3/engine/EventQueueConcurrentLoadTest.java | 362 ++--
.../jcs3/engine/MockCacheServiceNonLocal.java | 146 +-
.../engine/ZombieCacheServiceNonLocalUnitTest.java | 50 +-
.../control/CompositeCacheDiskUsageUnitTest.java | 496 +++---
.../engine/control/CompositeCacheUnitTest.java | 152 +-
.../engine/control/MockCompositeCacheManager.java | 76 +-
.../jcs3/engine/control/MockElementSerializer.java | 16 +-
.../control/event/ElementEventHandlerMockImpl.java | 132 +-
.../control/event/SimpleEventHandlingUnitTest.java | 406 ++---
.../CacheEventLoggerDebugLoggerUnitTest.java | 36 +-
.../jcs3/engine/logging/MockCacheEventLogger.java | 38 +-
.../jcs3/engine/memory/MockMemoryCache.java | 148 +-
.../memory/fifo/FIFOMemoryCacheUnitTest.java | 32 +-
.../lru/LHMLRUMemoryCacheConcurrentUnitTest.java | 62 +-
.../memory/lru/LHMLRUMemoryCacheUnitTest.java | 176 +-
.../lru/LRUMemoryCacheConcurrentUnitTest.java | 62 +-
.../engine/memory/mru/LRUvsMRUPerformanceTest.java | 54 +-
.../engine/memory/mru/MRUMemoryCacheUnitTest.java | 176 +-
.../memory/shrinking/ShrinkerThreadUnitTest.java | 22 +-
.../soft/SoftReferenceMemoryCacheUnitTest.java | 122 +-
.../UDPDiscoverySenderEncryptedUnitTest.java | 40 +-
.../discovery/UDPDiscoveryServiceUnitTest.java | 58 +-
.../jcs3/utils/discovery/UDPDiscoveryUnitTest.java | 44 +-
.../commons/jcs3/utils/props/PropertyLoader.java | 28 +-
.../CompressingSerializerUnitTest.java | 42 +-
.../EncryptingSerializerUnitTest.java | 40 +-
.../SerializationConversionUtilUnitTest.java | 132 +-
.../serialization/StandardSerializerUnitTest.java | 22 +-
.../utils/struct/DoubleLinkedListUnitTest.java | 48 +-
.../struct/JCSvsCommonsLRUMapPerformanceTest.java | 44 +-
.../utils/struct/LRUMapConcurrentUnitTest.java | 118 +-
.../jcs3/utils/struct/LRUMapPerformanceTest.java | 30 +-
.../commons/jcs3/utils/struct/LRUMapUnitTest.java | 72 +-
.../threadpool/ThreadPoolManagerUnitTest.java | 30 +-
.../jcs3/utils/zip/CompressionUtilUnitTest.java | 36 +-
.../jcs3/jcache/extras/cdi/CacheManagerBean.java | 48 +-
.../jcs3/jcache/extras/cdi/CacheProviderBean.java | 48 +-
.../jcache/extras/cdi/ExtraJCacheExtension.java | 46 +-
.../jcache/extras/loader/CacheLoaderAdapter.java | 12 +-
.../jcache/extras/loader/CompositeCacheLoader.java | 24 +-
.../jcs3/jcache/extras/web/InMemoryResponse.java | 190 +-
.../jcs3/jcache/extras/web/JCacheFilter.java | 292 ++--
.../jcache/extras/writer/AsyncCacheWriter.java | 122 +-
.../jcache/extras/writer/CacheWriterAdapter.java | 14 +-
.../jcache/extras/writer/CompositeCacheWriter.java | 40 +-
.../extras/cdi/ExtraJCacheExtensionTest.java | 46 +-
.../extras/loader/CacheLoaderAdapterTest.java | 2 +-
.../extras/loader/CompositeCacheLoaderTest.java | 2 +-
.../jcs3/jcache/extras/web/JCacheFilterTest.java | 116 +-
.../extras/writer/CacheWriterAdapterTest.java | 10 +-
.../extras/writer/CompositeCacheWriterTest.java | 18 +-
.../jcache/openjpa/OpenJPAJCacheDataCache.java | 58 +-
.../openjpa/OpenJPAJCacheDataCacheManager.java | 50 +-
.../jcache/openjpa/OpenJPAJCacheDerivation.java | 24 +-
.../jcache/openjpa/OpenJPAJCacheQueryCache.java | 40 +-
.../jcache/openjpa/OpenJPAJCacheDataCacheTest.java | 52 +-
.../jcache/EnsureCDIIsTestedWhenTCKsRunTest.java | 2 +-
.../org/apache/commons/jcs3/jcache/JCSCache.java | 916 +++++-----
.../commons/jcs3/jcache/JCSCacheEntryEvent.java | 16 +-
.../commons/jcs3/jcache/JCSCachingManager.java | 250 +--
.../commons/jcs3/jcache/JCSCachingProvider.java | 86 +-
.../commons/jcs3/jcache/JCSConfiguration.java | 66 +-
.../apache/commons/jcs3/jcache/JCSListener.java | 54 +-
.../commons/jcs3/jcache/JCSMutableEntry.java | 16 +-
.../org/apache/commons/jcs3/jcache/NoWriter.java | 14 +-
.../org/apache/commons/jcs3/jcache/Statistics.java | 52 +-
.../commons/jcs3/jcache/TempStateCacheView.java | 282 +--
.../commons/jcs3/jcache/cdi/CDIJCacheHelper.java | 860 ++++-----
.../jcache/cdi/CacheInvocationContextImpl.java | 58 +-
.../jcache/cdi/CacheInvocationParameterImpl.java | 16 +-
.../jcs3/jcache/cdi/CacheMethodDetailsImpl.java | 12 +-
.../jcs3/jcache/cdi/CacheResolverFactoryImpl.java | 32 +-
.../cdi/MakeJCacheCDIInterceptorFriendly.java | 196 +--
.../jmx/ConfigurableMBeanServerIdBuilder.java | 138 +-
.../commons/jcs3/jcache/jmx/JCSCacheMXBean.java | 32 +-
.../jcs3/jcache/jmx/JCSCacheStatisticsMXBean.java | 80 +-
.../org/apache/commons/jcs3/jcache/jmx/JMXs.java | 22 +-
.../commons/jcs3/jcache/lang/Subsitutor.java | 4 +-
.../jcs3/jcache/proxy/ClassLoaderAwareCache.java | 186 +-
.../jcs3/jcache/proxy/ExceptionWrapperHandler.java | 12 +-
.../org/apache/commons/jcs3/jcache/CacheTest.java | 92 +-
.../commons/jcs3/jcache/CachingProviderTest.java | 12 +-
.../commons/jcs3/jcache/ExpiryListenerTest.java | 36 +-
.../commons/jcs3/jcache/ImmediateExpiryTest.java | 2 +-
.../commons/jcs3/jcache/NotSerializableTest.java | 20 +-
.../jcs3/jcache/cdi/CDIJCacheHelperTest.java | 70 +-
326 files changed, 22178 insertions(+), 22178 deletions(-)
(commons-jcs) 01/02: Normalize test method names
Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git
commit 159accd3340df0479c1408e2b8750fd8f2e443a5
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Nov 3 11:08:39 2023 -0400
Normalize test method names
---
.../commons/jcs3/jcache/extras/cdi/ExtraJCacheExtensionTest.java | 4 ++--
.../commons/jcs3/jcache/extras/loader/CacheLoaderAdapterTest.java | 2 +-
.../jcs3/jcache/extras/loader/CompositeCacheLoaderTest.java | 2 +-
.../commons/jcs3/jcache/extras/writer/CacheWriterAdapterTest.java | 2 +-
.../jcs3/jcache/extras/writer/CompositeCacheWriterTest.java | 2 +-
.../commons/jcs3/jcache/openjpa/OpenJPAJCacheDataCacheTest.java | 4 ++--
.../commons/jcs3/jcache/EnsureCDIIsTestedWhenTCKsRunTest.java | 2 +-
.../src/test/java/org/apache/commons/jcs3/jcache/CacheTest.java | 8 ++++----
.../java/org/apache/commons/jcs3/jcache/CachingProviderTest.java | 4 ++--
.../java/org/apache/commons/jcs3/jcache/ExpiryListenerTest.java | 2 +-
.../java/org/apache/commons/jcs3/jcache/ImmediateExpiryTest.java | 2 +-
.../java/org/apache/commons/jcs3/jcache/NotSerializableTest.java | 2 +-
.../org/apache/commons/jcs3/jcache/cdi/CDIJCacheHelperTest.java | 2 +-
13 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/cdi/ExtraJCacheExtensionTest.java b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/cdi/ExtraJCacheExtensionTest.java
index 49f065d2..b63245cb 100644
--- a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/cdi/ExtraJCacheExtensionTest.java
+++ b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/cdi/ExtraJCacheExtensionTest.java
@@ -63,13 +63,13 @@ public class ExtraJCacheExtensionTest
private BeanWithInjections bean;
@Test
- public void defaultCacheManager()
+ public void testDefaultCacheManager()
{
assertNotNull(bean.getMgr());
}
@Test
- public void defaultCacheProvider()
+ public void testDefaultCacheProvider()
{
assertNotNull(bean.getProvider());
}
diff --git a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CacheLoaderAdapterTest.java b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CacheLoaderAdapterTest.java
index 91a9155e..f36fd317 100644
--- a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CacheLoaderAdapterTest.java
+++ b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CacheLoaderAdapterTest.java
@@ -54,7 +54,7 @@ public class CacheLoaderAdapterTest
private Cache<String, String> cache;
@Test
- public void checkLoadAll()
+ public void testCheckLoadAll()
{
assertFalse(cache.iterator().hasNext());
assertEquals("foo", cache.get("foo"));
diff --git a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CompositeCacheLoaderTest.java b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CompositeCacheLoaderTest.java
index 38997482..beb7a366 100644
--- a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CompositeCacheLoaderTest.java
+++ b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/loader/CompositeCacheLoaderTest.java
@@ -67,7 +67,7 @@ public class CompositeCacheLoaderTest
private Cache<String, String> cache;
@Test
- public void checkComposite()
+ public void testCheckComposite()
{
cache.get("foo");
assertEquals(2, count.get());
diff --git a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CacheWriterAdapterTest.java b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CacheWriterAdapterTest.java
index b71f61ab..59806726 100644
--- a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CacheWriterAdapterTest.java
+++ b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CacheWriterAdapterTest.java
@@ -63,7 +63,7 @@ public class CacheWriterAdapterTest
private Cache<String, String> cache;
@Test
- public void checkWriteAllAndDeleteAll()
+ public void testCheckWriteAllAndDeleteAll()
{
assertTrue(copy.isEmpty());
assertFalse(cache.iterator().hasNext());
diff --git a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CompositeCacheWriterTest.java b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CompositeCacheWriterTest.java
index 77c412e5..82fede84 100644
--- a/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CompositeCacheWriterTest.java
+++ b/commons-jcs3-jcache-extras/src/test/java/org/apache/commons/jcs3/jcache/extras/writer/CompositeCacheWriterTest.java
@@ -81,7 +81,7 @@ public class CompositeCacheWriterTest
private Cache<String, String> cache;
@Test
- public void checkComposite()
+ public void testCheckComposite()
{
cache.put("a", "b");
assertEquals("b", copy1.get("a"));
diff --git a/commons-jcs3-jcache-openjpa/src/test/java/org/apache/commons/jcs3/jcache/openjpa/OpenJPAJCacheDataCacheTest.java b/commons-jcs3-jcache-openjpa/src/test/java/org/apache/commons/jcs3/jcache/openjpa/OpenJPAJCacheDataCacheTest.java
index 091ec9b1..e200991a 100644
--- a/commons-jcs3-jcache-openjpa/src/test/java/org/apache/commons/jcs3/jcache/openjpa/OpenJPAJCacheDataCacheTest.java
+++ b/commons-jcs3-jcache-openjpa/src/test/java/org/apache/commons/jcs3/jcache/openjpa/OpenJPAJCacheDataCacheTest.java
@@ -61,7 +61,7 @@ public class OpenJPAJCacheDataCacheTest
}};
@Test
- public void entity()
+ public void testEntity()
{
final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jcache", props);
final OpenJPAConfiguration conf = OpenJPAEntityManagerFactorySPI.class.cast(emf).getConfiguration();
@@ -84,7 +84,7 @@ public class OpenJPAJCacheDataCacheTest
}
@Test
- public void query()
+ public void testQuery()
{
final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jcache", props);
final OpenJPAConfiguration conf = OpenJPAEntityManagerFactorySPI.class.cast(emf).getConfiguration();
diff --git a/commons-jcs3-jcache-tck/src/test/java/org/apache/commons/jcs3/jcache/EnsureCDIIsTestedWhenTCKsRunTest.java b/commons-jcs3-jcache-tck/src/test/java/org/apache/commons/jcs3/jcache/EnsureCDIIsTestedWhenTCKsRunTest.java
index 2867b28f..98c7cc87 100644
--- a/commons-jcs3-jcache-tck/src/test/java/org/apache/commons/jcs3/jcache/EnsureCDIIsTestedWhenTCKsRunTest.java
+++ b/commons-jcs3-jcache-tck/src/test/java/org/apache/commons/jcs3/jcache/EnsureCDIIsTestedWhenTCKsRunTest.java
@@ -34,7 +34,7 @@ import org.junit.Test;
public class EnsureCDIIsTestedWhenTCKsRunTest
{
@Test
- public void checkOWBProvider()
+ public void testCheckOWBProvider()
{
try {
final Iterator<BeanProvider> iterator = ServiceLoader.load(BeanProvider.class).iterator();
diff --git a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CacheTest.java b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CacheTest.java
index 942c5e3e..3dbca30d 100644
--- a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CacheTest.java
+++ b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CacheTest.java
@@ -53,7 +53,7 @@ import org.junit.Test;
public class CacheTest
{
@Test
- public void accessExpiry() throws InterruptedException
+ public void testAccessExpiry() throws InterruptedException
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager(cachingProvider.getDefaultURI(),
@@ -88,7 +88,7 @@ public class CacheTest
}
@Test
- public void getPut()
+ public void testGetPut()
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
@@ -103,7 +103,7 @@ public class CacheTest
}
@Test
- public void listeners()
+ public void testListeners()
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
@@ -220,7 +220,7 @@ public class CacheTest
}
@Test
- public void loader()
+ public void testLoader()
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
diff --git a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CachingProviderTest.java b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CachingProviderTest.java
index a0a6a009..053c2a88 100644
--- a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CachingProviderTest.java
+++ b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/CachingProviderTest.java
@@ -29,13 +29,13 @@ import org.junit.Test;
public class CachingProviderTest
{
@Test
- public void findProvider()
+ public void testFindProvider()
{
assertNotNull(Caching.getCachingProvider());
}
@Test
- public void createCacheMgr()
+ public void testCreateCacheMgr()
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
assertNotNull(cachingProvider.getCacheManager());
diff --git a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ExpiryListenerTest.java b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ExpiryListenerTest.java
index 8b0f9235..f892dea0 100644
--- a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ExpiryListenerTest.java
+++ b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ExpiryListenerTest.java
@@ -45,7 +45,7 @@ import org.junit.Test;
public class ExpiryListenerTest {
@Test
- public void listener() throws InterruptedException {
+ public void testListener() throws InterruptedException {
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
final CacheEntryExpiredListenerImpl listener = new CacheEntryExpiredListenerImpl();
diff --git a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ImmediateExpiryTest.java b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ImmediateExpiryTest.java
index ea5f6384..ca931462 100644
--- a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ImmediateExpiryTest.java
+++ b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/ImmediateExpiryTest.java
@@ -35,7 +35,7 @@ import org.junit.Test;
public class ImmediateExpiryTest
{
@Test
- public void immediate()
+ public void testImmediate()
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
diff --git a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/NotSerializableTest.java b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/NotSerializableTest.java
index 2f1bec16..da9f9f8e 100644
--- a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/NotSerializableTest.java
+++ b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/NotSerializableTest.java
@@ -33,7 +33,7 @@ import org.junit.Test;
public class NotSerializableTest
{
@Test
- public void run()
+ public void testRun()
{
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
diff --git a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/cdi/CDIJCacheHelperTest.java b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/cdi/CDIJCacheHelperTest.java
index 37b61dc0..dcb49b19 100644
--- a/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/cdi/CDIJCacheHelperTest.java
+++ b/commons-jcs3-jcache/src/test/java/org/apache/commons/jcs3/jcache/cdi/CDIJCacheHelperTest.java
@@ -36,7 +36,7 @@ import org.junit.Test;
public class CDIJCacheHelperTest
{
@Test
- public void proxyCacheDefaults()
+ public void testProxyCacheDefaults()
{
final CDIJCacheHelper helper = new CDIJCacheHelper();
(commons-jcs) 02/02: Sort members
Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git
commit 4640fe5e8f4118a93e2f95e2f440ff1dd7aacb23
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Nov 3 11:09:45 2023 -0400
Sort members
---
.../src/main/java/org/apache/commons/jcs3/JCS.java | 160 +-
.../commons/jcs3/access/AbstractCacheAccess.java | 112 +-
.../apache/commons/jcs3/access/CacheAccess.java | 152 +-
.../commons/jcs3/access/GroupCacheAccess.java | 86 +-
.../commons/jcs3/access/behavior/ICacheAccess.java | 94 +-
.../access/behavior/ICacheAccessManagement.java | 74 +-
.../jcs3/access/behavior/IGroupCacheAccess.java | 30 +-
.../jcs3/access/exception/CacheException.java | 16 +-
.../commons/jcs3/admin/CacheElementInfo.java | 26 +-
.../apache/commons/jcs3/admin/CacheRegionInfo.java | 46 +-
.../jcs3/admin/CountingOnlyOutputStream.java | 20 +-
.../apache/commons/jcs3/admin/JCSAdminBean.java | 206 +--
.../org/apache/commons/jcs3/admin/JCSJMXBean.java | 28 +-
.../jcs3/auxiliary/AbstractAuxiliaryCache.java | 160 +-
.../AbstractAuxiliaryCacheAttributes.java | 68 +-
.../AbstractAuxiliaryCacheEventLogging.java | 214 +--
.../auxiliary/AbstractAuxiliaryCacheMonitor.java | 74 +-
.../commons/jcs3/auxiliary/AuxiliaryCache.java | 22 +-
.../jcs3/auxiliary/AuxiliaryCacheAttributes.java | 42 +-
.../jcs3/auxiliary/AuxiliaryCacheFactory.java | 22 +-
.../jcs3/auxiliary/disk/AbstractDiskCache.java | 878 +++++-----
.../disk/AbstractDiskCacheAttributes.java | 154 +-
.../jcs3/auxiliary/disk/PurgatoryElement.java | 86 +-
.../disk/behavior/IDiskCacheAttributes.java | 58 +-
.../jcs3/auxiliary/disk/block/BlockDisk.java | 348 ++--
.../jcs3/auxiliary/disk/block/BlockDiskCache.java | 588 +++----
.../disk/block/BlockDiskCacheAttributes.java | 44 +-
.../disk/block/BlockDiskElementDescriptor.java | 46 +-
.../auxiliary/disk/block/BlockDiskKeyStore.java | 6 +-
.../jcs3/auxiliary/disk/indexed/IndexedDisk.java | 224 +--
.../auxiliary/disk/indexed/IndexedDiskCache.java | 1830 +++++++++----------
.../disk/indexed/IndexedDiskCacheAttributes.java | 66 +-
.../disk/indexed/IndexedDiskElementDescriptor.java | 64 +-
.../jcs3/auxiliary/disk/jdbc/JDBCDiskCache.java | 594 +++----
.../disk/jdbc/JDBCDiskCacheAttributes.java | 212 +--
.../auxiliary/disk/jdbc/JDBCDiskCacheFactory.java | 140 +-
.../jcs3/auxiliary/disk/jdbc/ShrinkerThread.java | 50 +-
.../jcs3/auxiliary/disk/jdbc/TableState.java | 20 +-
.../disk/jdbc/dsfactory/DataSourceFactory.java | 34 +-
.../disk/jdbc/dsfactory/JndiDataSourceFactory.java | 54 +-
.../dsfactory/SharedPoolDataSourceFactory.java | 120 +-
.../auxiliary/disk/jdbc/mysql/MySQLDiskCache.java | 70 +-
.../disk/jdbc/mysql/MySQLDiskCacheAttributes.java | 32 +-
.../disk/jdbc/mysql/MySQLDiskCacheFactory.java | 68 +-
.../disk/jdbc/mysql/MySQLTableOptimizer.java | 74 +-
.../jcs3/auxiliary/lateral/LateralCache.java | 354 ++--
.../auxiliary/lateral/LateralCacheAttributes.java | 126 +-
.../jcs3/auxiliary/lateral/LateralCacheNoWait.java | 346 ++--
.../lateral/LateralCacheNoWaitFacade.java | 328 ++--
.../lateral/LateralElementDescriptor.java | 22 +-
.../lateral/behavior/ILateralCacheAttributes.java | 108 +-
.../lateral/behavior/ILateralCacheListener.java | 18 +-
.../lateral/socket/tcp/LateralTCPCacheFactory.java | 260 +--
.../socket/tcp/LateralTCPDiscoveryListener.java | 260 +--
.../lateral/socket/tcp/LateralTCPListener.java | 640 +++----
.../lateral/socket/tcp/LateralTCPSender.java | 28 +-
.../lateral/socket/tcp/LateralTCPService.java | 220 +--
.../socket/tcp/TCPLateralCacheAttributes.java | 258 +--
.../tcp/behavior/ITCPLateralCacheAttributes.java | 212 +--
.../remote/AbstractRemoteAuxiliaryCache.java | 560 +++---
.../remote/AbstractRemoteCacheListener.java | 100 +-
.../remote/AbstractRemoteCacheNoWaitFacade.java | 242 +--
.../remote/CommonRemoteCacheAttributes.java | 150 +-
.../commons/jcs3/auxiliary/remote/RemoteCache.java | 94 +-
.../auxiliary/remote/RemoteCacheAttributes.java | 124 +-
.../jcs3/auxiliary/remote/RemoteCacheFactory.java | 54 +-
.../jcs3/auxiliary/remote/RemoteCacheManager.java | 190 +-
.../jcs3/auxiliary/remote/RemoteCacheNoWait.java | 326 ++--
.../auxiliary/remote/RemoteCacheNoWaitFacade.java | 70 +-
.../jcs3/auxiliary/remote/RemoteLocation.java | 72 +-
.../commons/jcs3/auxiliary/remote/RemoteUtils.java | 174 +-
.../behavior/ICommonRemoteCacheAttributes.java | 110 +-
.../remote/behavior/IRemoteCacheAttributes.java | 108 +-
.../remote/behavior/IRemoteCacheClient.java | 16 +-
.../remote/behavior/IRemoteCacheListener.java | 62 +-
.../remote/http/client/AbstractHttpClient.java | 30 +-
.../remote/http/client/RemoteHttpCache.java | 34 +-
.../http/client/RemoteHttpCacheAttributes.java | 106 +-
.../remote/http/client/RemoteHttpCacheClient.java | 266 +--
.../http/client/RemoteHttpCacheDispatcher.java | 58 +-
.../remote/http/client/RemoteHttpCacheFactory.java | 24 +-
.../remote/http/client/RemoteHttpCacheMonitor.java | 32 +-
.../http/server/AbstractRemoteCacheService.java | 448 ++---
.../server/RemoteHttpCacheServerAttributes.java | 26 +-
.../remote/http/server/RemoteHttpCacheService.java | 94 +-
.../remote/http/server/RemoteHttpCacheServlet.java | 242 +--
.../auxiliary/remote/server/RemoteCacheServer.java | 1278 +++++++-------
.../remote/server/RemoteCacheServerAttributes.java | 80 +-
.../remote/server/RemoteCacheServerFactory.java | 394 ++---
.../remote/server/RemoteCacheStartupServlet.java | 148 +-
.../TimeoutConfigurableRMISocketFactory.java | 12 +-
.../behavior/IRemoteCacheServerAttributes.java | 56 +-
.../remote/util/RemoteCacheRequestFactory.java | 94 +-
.../auxiliary/remote/value/RemoteCacheRequest.java | 84 +-
.../remote/value/RemoteCacheResponse.java | 28 +-
.../jcs3/engine/AbstractCacheEventQueue.java | 440 ++---
.../apache/commons/jcs3/engine/CacheAdaptor.java | 32 +-
.../apache/commons/jcs3/engine/CacheElement.java | 90 +-
.../jcs3/engine/CacheElementSerialized.java | 88 +-
.../jcs3/engine/CacheEventQueueFactory.java | 32 +-
.../org/apache/commons/jcs3/engine/CacheInfo.java | 10 +-
.../commons/jcs3/engine/CacheWatchRepairable.java | 84 +-
.../jcs3/engine/CompositeCacheAttributes.java | 254 +--
.../commons/jcs3/engine/ElementAttributes.java | 292 ++--
.../commons/jcs3/engine/PooledCacheEventQueue.java | 76 +-
.../commons/jcs3/engine/ZombieCacheService.java | 64 +-
.../jcs3/engine/ZombieCacheServiceNonLocal.java | 238 +--
.../commons/jcs3/engine/ZombieCacheWatch.java | 12 +-
.../commons/jcs3/engine/behavior/ICache.java | 68 +-
.../jcs3/engine/behavior/ICacheElement.java | 14 +-
.../jcs3/engine/behavior/ICacheEventQueue.java | 66 +-
.../jcs3/engine/behavior/ICacheListener.java | 34 +-
.../jcs3/engine/behavior/ICacheObserver.java | 26 +-
.../jcs3/engine/behavior/ICacheService.java | 46 +-
.../engine/behavior/ICacheServiceNonLocal.java | 70 +-
.../engine/behavior/ICompositeCacheAttributes.java | 192 +-
.../engine/behavior/ICompositeCacheManager.java | 14 +-
.../jcs3/engine/behavior/IElementAttributes.java | 172 +-
.../jcs3/engine/behavior/IElementSerializer.java | 238 +--
.../jcs3/engine/behavior/IShutdownObservable.java | 10 +-
.../jcs3/engine/control/CompositeCache.java | 1838 ++++++++++----------
.../engine/control/CompositeCacheConfigurator.java | 508 +++---
.../jcs3/engine/control/CompositeCacheManager.java | 778 ++++-----
.../engine/control/event/ElementEventQueue.java | 28 +-
.../commons/jcs3/engine/logging/CacheEvent.java | 72 +-
.../jcs3/engine/logging/behavior/ICacheEvent.java | 34 +-
.../engine/logging/behavior/ICacheEventLogger.java | 14 +-
.../AbstractDoubleLinkedListMemoryCache.java | 372 ++--
.../jcs3/engine/memory/AbstractMemoryCache.java | 432 ++---
.../jcs3/engine/memory/behavior/IMemoryCache.java | 138 +-
.../jcs3/engine/memory/fifo/FIFOMemoryCache.java | 22 +-
.../jcs3/engine/memory/lru/LHMLRUMemoryCache.java | 186 +-
.../jcs3/engine/memory/lru/LRUMemoryCache.java | 22 +-
.../jcs3/engine/memory/mru/MRUMemoryCache.java | 22 +-
.../memory/soft/SoftReferenceMemoryCache.java | 90 +-
.../commons/jcs3/engine/stats/CacheStats.java | 28 +-
.../commons/jcs3/engine/stats/StatElement.java | 32 +-
.../apache/commons/jcs3/engine/stats/Stats.java | 12 +-
.../jcs3/engine/stats/behavior/ICacheStats.java | 18 +-
.../jcs3/engine/stats/behavior/IStatElement.java | 22 +-
.../commons/jcs3/engine/stats/behavior/IStats.java | 12 +-
.../jcs3/io/ObjectInputStreamClassLoaderAware.java | 82 +-
.../org/apache/commons/jcs3/log/JulLogAdapter.java | 184 +-
.../org/apache/commons/jcs3/log/JulLogFactory.java | 40 +-
.../main/java/org/apache/commons/jcs3/log/Log.java | 48 +-
.../org/apache/commons/jcs3/log/Log4j2Factory.java | 40 +-
.../apache/commons/jcs3/log/Log4j2LogAdapter.java | 124 +-
.../org/apache/commons/jcs3/log/LogFactory.java | 24 +-
.../org/apache/commons/jcs3/log/LogManager.java | 76 +-
.../apache/commons/jcs3/log/MessageFormatter.java | 34 +-
.../commons/jcs3/utils/access/JCSWorkerHelper.java | 22 +-
.../commons/jcs3/utils/config/OptionConverter.java | 290 +--
.../commons/jcs3/utils/config/PropertySetter.java | 220 +--
.../jcs3/utils/discovery/DiscoveredService.java | 96 +-
.../utils/discovery/UDPDiscoveryAttributes.java | 156 +-
.../jcs3/utils/discovery/UDPDiscoveryManager.java | 18 +-
.../jcs3/utils/discovery/UDPDiscoveryMessage.java | 66 +-
.../jcs3/utils/discovery/UDPDiscoveryReceiver.java | 200 +--
.../jcs3/utils/discovery/UDPDiscoverySender.java | 146 +-
.../jcs3/utils/discovery/UDPDiscoveryService.java | 338 ++--
.../utils/serialization/CompressingSerializer.java | 30 +-
.../utils/serialization/EncryptingSerializer.java | 152 +-
.../serialization/SerializationConversionUtil.java | 82 +-
.../utils/serialization/StandardSerializer.java | 42 +-
.../utils/servlet/JCSServletContextListener.java | 20 +-
.../commons/jcs3/utils/struct/AbstractLRUMap.java | 280 +--
.../jcs3/utils/struct/DoubleLinkedList.java | 118 +-
.../jcs3/utils/struct/LRUElementDescriptor.java | 12 +-
.../jcs3/utils/threadpool/DaemonThreadFactory.java | 2 +-
.../jcs3/utils/threadpool/PoolConfiguration.java | 162 +-
.../jcs3/utils/threadpool/ThreadPoolManager.java | 238 +--
.../commons/jcs3/utils/zip/CompressionUtil.java | 114 +-
.../jcs3/JCSConcurrentCacheAccessUnitTest.java | 80 +-
.../jcs3/JCSRemovalSimpleConcurrentTest.java | 82 +-
.../org/apache/commons/jcs3/JCSThrashTest.java | 248 +--
.../java/org/apache/commons/jcs3/JCSUnitTest.java | 32 +-
.../jcs3/JCSvsHashtablePerformanceTest.java | 50 +-
.../org/apache/commons/jcs3/RemovalTestUtil.java | 56 +-
.../commons/jcs3/TestLogConfigurationUtil.java | 50 +-
.../apache/commons/jcs3/TestTCPLateralCache.java | 92 +-
.../commons/jcs3/access/CacheAccessUnitTest.java | 340 ++--
.../jcs3/access/GroupCacheAccessUnitTest.java | 198 +--
.../commons/jcs3/access/TestCacheAccess.java | 974 +++++------
.../commons/jcs3/admin/AdminBeanUnitTest.java | 84 +-
.../commons/jcs3/admin/CountingStreamUnitTest.java | 32 +-
.../AuxiliaryCacheConfiguratorUnitTest.java | 40 +-
.../commons/jcs3/auxiliary/MockAuxiliaryCache.java | 120 +-
.../jcs3/auxiliary/MockCacheEventLogger.java | 30 +-
.../auxiliary/disk/AbstractDiskCacheUnitTest.java | 270 +--
.../auxiliary/disk/PurgatoryElementUnitTest.java | 22 +-
.../disk/block/AbstractBlockDiskCacheUnitTest.java | 552 +++---
.../block/BlockDiskCacheConcurrentUnitTest.java | 136 +-
.../disk/block/BlockDiskCacheKeyStoreUnitTest.java | 96 +-
.../BlockDiskCacheRandomConcurrentTestUtil.java | 12 +-
...BlockDiskCacheSameRegionConcurrentUnitTest.java | 88 +-
.../disk/block/BlockDiskCacheSteadyLoadTest.java | 28 +-
.../auxiliary/disk/block/BlockDiskUnitTest.java | 242 +--
.../block/HugeQuantityBlockDiskCacheLoadTest.java | 28 +-
.../indexed/AbstractIndexDiskCacheUnitTest.java | 1072 ++++++------
.../auxiliary/disk/indexed/DiskTestObjectUtil.java | 102 +-
.../indexed/HugeQuantityIndDiskCacheLoadTest.java | 30 +-
.../IndexedDiskCacheConcurrentUnitTest.java | 122 +-
.../IndexedDiskCacheDefragPerformanceTest.java | 96 +-
.../indexed/IndexedDiskCacheKeyStoreUnitTest.java | 78 +-
.../indexed/IndexedDiskCacheNoMemoryUnitTest.java | 86 +-
...dexedDiskCacheSameRegionConcurrentUnitTest.java | 154 +-
.../indexed/IndexedDiskCacheSteadyLoadTest.java | 28 +-
.../auxiliary/disk/indexed/LRUMapSizeVsCount.java | 30 +-
.../jcs3/auxiliary/disk/jdbc/HsqlSetupUtil.java | 26 +-
.../disk/jdbc/JDBCDataSourceFactoryUnitTest.java | 170 +-
.../disk/jdbc/JDBCDiskCacheSharedPoolUnitTest.java | 50 +-
.../disk/jdbc/JDBCDiskCacheShrinkUnitTest.java | 62 +-
.../auxiliary/disk/jdbc/JDBCDiskCacheUnitTest.java | 46 +-
.../jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java | 102 +-
.../mysql/MySQLDiskCacheHsqlBackedUnitTest.java | 50 +-
.../mysql/util/ScheduleParserUtilUnitTest.java | 90 +-
.../lateral/LateralCacheNoWaitFacadeUnitTest.java | 34 +-
.../tcp/LateralTCPConcurrentRandomTestUtil.java | 22 +-
.../tcp/LateralTCPDiscoveryListenerUnitTest.java | 148 +-
.../LateralTCPFilterRemoveHashCodeUnitTest.java | 44 +-
.../tcp/LateralTCPIssueRemoveOnPutUnitTest.java | 130 +-
.../lateral/socket/tcp/TestTCPLateralUnitTest.java | 226 +--
.../auxiliary/remote/MockRemoteCacheClient.java | 146 +-
.../auxiliary/remote/MockRemoteCacheListener.java | 26 +-
.../auxiliary/remote/MockRemoteCacheService.java | 136 +-
.../auxiliary/remote/RemoteCacheClientTester.java | 174 +-
.../remote/RemoteCacheNoWaitUnitTest.java | 74 +-
.../jcs3/auxiliary/remote/RemoteCacheUnitTest.java | 120 +-
.../jcs3/auxiliary/remote/TestRemoteCache.java | 46 +-
.../auxiliary/remote/TestRemoteCacheFactory.java | 64 +-
.../remote/ZombieRemoteCacheServiceUnitTest.java | 50 +-
.../http/client/RemoteHttpCacheClientUnitTest.java | 68 +-
.../server/RemoteHttpCacheServiceUnitTest.java | 34 +-
.../server/RemoteHttpCacheServletUnitTest.java | 46 +-
.../remote/server/MockRMISocketFactory.java | 34 +-
.../RemoteCacheServerAttributesUnitTest.java | 16 +-
.../server/RemoteCacheServerFactoryUnitTest.java | 102 +-
.../remote/server/RemoteCacheServerUnitTest.java | 274 +--
.../util/RemoteCacheRequestFactoryUnitTest.java | 42 +-
.../engine/CacheEventQueueFactoryUnitTest.java | 12 +-
.../jcs3/engine/EventQueueConcurrentLoadTest.java | 362 ++--
.../jcs3/engine/MockCacheServiceNonLocal.java | 146 +-
.../engine/ZombieCacheServiceNonLocalUnitTest.java | 50 +-
.../control/CompositeCacheDiskUsageUnitTest.java | 496 +++---
.../engine/control/CompositeCacheUnitTest.java | 152 +-
.../engine/control/MockCompositeCacheManager.java | 76 +-
.../jcs3/engine/control/MockElementSerializer.java | 16 +-
.../control/event/ElementEventHandlerMockImpl.java | 132 +-
.../control/event/SimpleEventHandlingUnitTest.java | 406 ++---
.../CacheEventLoggerDebugLoggerUnitTest.java | 36 +-
.../jcs3/engine/logging/MockCacheEventLogger.java | 38 +-
.../jcs3/engine/memory/MockMemoryCache.java | 148 +-
.../memory/fifo/FIFOMemoryCacheUnitTest.java | 32 +-
.../lru/LHMLRUMemoryCacheConcurrentUnitTest.java | 62 +-
.../memory/lru/LHMLRUMemoryCacheUnitTest.java | 176 +-
.../lru/LRUMemoryCacheConcurrentUnitTest.java | 62 +-
.../engine/memory/mru/LRUvsMRUPerformanceTest.java | 54 +-
.../engine/memory/mru/MRUMemoryCacheUnitTest.java | 176 +-
.../memory/shrinking/ShrinkerThreadUnitTest.java | 22 +-
.../soft/SoftReferenceMemoryCacheUnitTest.java | 122 +-
.../UDPDiscoverySenderEncryptedUnitTest.java | 40 +-
.../discovery/UDPDiscoveryServiceUnitTest.java | 58 +-
.../jcs3/utils/discovery/UDPDiscoveryUnitTest.java | 44 +-
.../commons/jcs3/utils/props/PropertyLoader.java | 28 +-
.../CompressingSerializerUnitTest.java | 42 +-
.../EncryptingSerializerUnitTest.java | 40 +-
.../SerializationConversionUtilUnitTest.java | 132 +-
.../serialization/StandardSerializerUnitTest.java | 22 +-
.../utils/struct/DoubleLinkedListUnitTest.java | 48 +-
.../struct/JCSvsCommonsLRUMapPerformanceTest.java | 44 +-
.../utils/struct/LRUMapConcurrentUnitTest.java | 118 +-
.../jcs3/utils/struct/LRUMapPerformanceTest.java | 30 +-
.../commons/jcs3/utils/struct/LRUMapUnitTest.java | 72 +-
.../threadpool/ThreadPoolManagerUnitTest.java | 30 +-
.../jcs3/utils/zip/CompressionUtilUnitTest.java | 36 +-
.../jcs3/jcache/extras/cdi/CacheManagerBean.java | 48 +-
.../jcs3/jcache/extras/cdi/CacheProviderBean.java | 48 +-
.../jcache/extras/cdi/ExtraJCacheExtension.java | 46 +-
.../jcache/extras/loader/CacheLoaderAdapter.java | 12 +-
.../jcache/extras/loader/CompositeCacheLoader.java | 24 +-
.../jcs3/jcache/extras/web/InMemoryResponse.java | 190 +-
.../jcs3/jcache/extras/web/JCacheFilter.java | 292 ++--
.../jcache/extras/writer/AsyncCacheWriter.java | 122 +-
.../jcache/extras/writer/CacheWriterAdapter.java | 14 +-
.../jcache/extras/writer/CompositeCacheWriter.java | 40 +-
.../extras/cdi/ExtraJCacheExtensionTest.java | 42 +-
.../jcs3/jcache/extras/web/JCacheFilterTest.java | 116 +-
.../extras/writer/CacheWriterAdapterTest.java | 8 +-
.../extras/writer/CompositeCacheWriterTest.java | 16 +-
.../jcache/openjpa/OpenJPAJCacheDataCache.java | 58 +-
.../openjpa/OpenJPAJCacheDataCacheManager.java | 50 +-
.../jcache/openjpa/OpenJPAJCacheDerivation.java | 24 +-
.../jcache/openjpa/OpenJPAJCacheQueryCache.java | 40 +-
.../jcache/openjpa/OpenJPAJCacheDataCacheTest.java | 48 +-
.../org/apache/commons/jcs3/jcache/JCSCache.java | 916 +++++-----
.../commons/jcs3/jcache/JCSCacheEntryEvent.java | 16 +-
.../commons/jcs3/jcache/JCSCachingManager.java | 250 +--
.../commons/jcs3/jcache/JCSCachingProvider.java | 86 +-
.../commons/jcs3/jcache/JCSConfiguration.java | 66 +-
.../apache/commons/jcs3/jcache/JCSListener.java | 54 +-
.../commons/jcs3/jcache/JCSMutableEntry.java | 16 +-
.../org/apache/commons/jcs3/jcache/NoWriter.java | 14 +-
.../org/apache/commons/jcs3/jcache/Statistics.java | 52 +-
.../commons/jcs3/jcache/TempStateCacheView.java | 282 +--
.../commons/jcs3/jcache/cdi/CDIJCacheHelper.java | 860 ++++-----
.../jcache/cdi/CacheInvocationContextImpl.java | 58 +-
.../jcache/cdi/CacheInvocationParameterImpl.java | 16 +-
.../jcs3/jcache/cdi/CacheMethodDetailsImpl.java | 12 +-
.../jcs3/jcache/cdi/CacheResolverFactoryImpl.java | 32 +-
.../cdi/MakeJCacheCDIInterceptorFriendly.java | 196 +--
.../jmx/ConfigurableMBeanServerIdBuilder.java | 138 +-
.../commons/jcs3/jcache/jmx/JCSCacheMXBean.java | 32 +-
.../jcs3/jcache/jmx/JCSCacheStatisticsMXBean.java | 80 +-
.../org/apache/commons/jcs3/jcache/jmx/JMXs.java | 22 +-
.../commons/jcs3/jcache/lang/Subsitutor.java | 4 +-
.../jcs3/jcache/proxy/ClassLoaderAwareCache.java | 186 +-
.../jcs3/jcache/proxy/ExceptionWrapperHandler.java | 12 +-
.../org/apache/commons/jcs3/jcache/CacheTest.java | 84 +-
.../commons/jcs3/jcache/CachingProviderTest.java | 12 +-
.../commons/jcs3/jcache/ExpiryListenerTest.java | 34 +-
.../commons/jcs3/jcache/NotSerializableTest.java | 18 +-
.../jcs3/jcache/cdi/CDIJCacheHelperTest.java | 70 +-
322 files changed, 22162 insertions(+), 22162 deletions(-)
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/JCS.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/JCS.java
index 2543e661..97d36e95 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/JCS.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/JCS.java
@@ -49,56 +49,6 @@ public abstract class JCS
/** Cache manager use by the various forms of defineRegion and getAccess */
private static CompositeCacheManager cacheMgr;
- /**
- * Sets the file name that the cache manager will be initialized with. Only matters before the
- * instance is initialized.
- *
- * @param configFileName
- */
- public static void setConfigFilename( final String configFileName )
- {
- JCS.configFileName = configFileName;
- }
-
- /**
- * Sets the properties that the cache manager will be initialized with. Only
- * matters before the instance is initialized.
- *
- * @param configProps
- */
- public static void setConfigProperties( final Properties configProps )
- {
- JCS.configProps = configProps;
- }
-
- /**
- * Sets the log system. Must be called before getInstance is called
- * Predefined Log systems are {@link LogManager#LOGSYSTEM_JAVA_UTIL_LOGGING}
- * and {@link LogManager#LOGSYSTEM_LOG4J2}
- *
- * @param logSystem the logSystem to set
- */
- public static void setLogSystem(final String logSystem)
- {
- LogManager.setLogSystem(logSystem);
- }
-
- /**
- * Shut down the cache manager and set the instance to null
- */
- public static void shutdown()
- {
- synchronized ( JCS.class )
- {
- if ( cacheMgr != null && cacheMgr.isInitialized())
- {
- cacheMgr.shutDown();
- }
-
- cacheMgr = null;
- }
- }
-
/**
* Helper method which checks to make sure the cacheMgr class field is set, and if not requests
* an instance from CacheManagerFactory.
@@ -131,6 +81,51 @@ public abstract class JCS
}
}
+ /**
+ * Gets a GroupCacheAccess which accesses the provided region.
+ * <p>
+ * @param region Region that return GroupCacheAccess will provide access to
+ * @return A GroupCacheAccess which provides access to a given region.
+ * @throws CacheException
+ */
+ public static <K, V> GroupCacheAccess<K, V> getGroupCacheInstance( final String region )
+ throws CacheException
+ {
+ final CompositeCache<GroupAttrName<K>, V> cache = getCacheManager().getCache( region );
+ return new GroupCacheAccess<>( cache );
+ }
+
+ /**
+ * Gets a GroupCacheAccess which accesses the provided region.
+ * <p>
+ * @param region Region that return GroupCacheAccess will provide access to
+ * @param icca CacheAttributes for region
+ * @return A GroupCacheAccess which provides access to a given region.
+ * @throws CacheException
+ */
+ public static <K, V> GroupCacheAccess<K, V> getGroupCacheInstance( final String region, final ICompositeCacheAttributes icca )
+ throws CacheException
+ {
+ final CompositeCache<GroupAttrName<K>, V> cache = getCacheManager().getCache( region, icca );
+ return new GroupCacheAccess<>( cache );
+ }
+
+ /**
+ * Gets a GroupCacheAccess which accesses the provided region.
+ * <p>
+ * @param region Region that return CacheAccess will provide access to
+ * @param icca CacheAttributes for region
+ * @param eattr ElementAttributes for the region
+ * @return A GroupCacheAccess which provides access to a given region.
+ * @throws CacheException
+ */
+ public static <K, V> GroupCacheAccess<K, V> getGroupCacheInstance( final String region, final ICompositeCacheAttributes icca, final IElementAttributes eattr )
+ throws CacheException
+ {
+ final CompositeCache<GroupAttrName<K>, V> cache = getCacheManager().getCache( region, icca, eattr );
+ return new GroupCacheAccess<>( cache );
+ }
+
/**
* Gets a CacheAccess which accesses the provided region.
* <p>
@@ -177,47 +172,52 @@ public abstract class JCS
}
/**
- * Gets a GroupCacheAccess which accesses the provided region.
- * <p>
- * @param region Region that return GroupCacheAccess will provide access to
- * @return A GroupCacheAccess which provides access to a given region.
- * @throws CacheException
+ * Sets the file name that the cache manager will be initialized with. Only matters before the
+ * instance is initialized.
+ *
+ * @param configFileName
*/
- public static <K, V> GroupCacheAccess<K, V> getGroupCacheInstance( final String region )
- throws CacheException
+ public static void setConfigFilename( final String configFileName )
{
- final CompositeCache<GroupAttrName<K>, V> cache = getCacheManager().getCache( region );
- return new GroupCacheAccess<>( cache );
+ JCS.configFileName = configFileName;
}
/**
- * Gets a GroupCacheAccess which accesses the provided region.
- * <p>
- * @param region Region that return GroupCacheAccess will provide access to
- * @param icca CacheAttributes for region
- * @return A GroupCacheAccess which provides access to a given region.
- * @throws CacheException
+ * Sets the properties that the cache manager will be initialized with. Only
+ * matters before the instance is initialized.
+ *
+ * @param configProps
*/
- public static <K, V> GroupCacheAccess<K, V> getGroupCacheInstance( final String region, final ICompositeCacheAttributes icca )
- throws CacheException
+ public static void setConfigProperties( final Properties configProps )
{
- final CompositeCache<GroupAttrName<K>, V> cache = getCacheManager().getCache( region, icca );
- return new GroupCacheAccess<>( cache );
+ JCS.configProps = configProps;
}
/**
- * Gets a GroupCacheAccess which accesses the provided region.
- * <p>
- * @param region Region that return CacheAccess will provide access to
- * @param icca CacheAttributes for region
- * @param eattr ElementAttributes for the region
- * @return A GroupCacheAccess which provides access to a given region.
- * @throws CacheException
+ * Sets the log system. Must be called before getInstance is called
+ * Predefined Log systems are {@link LogManager#LOGSYSTEM_JAVA_UTIL_LOGGING}
+ * and {@link LogManager#LOGSYSTEM_LOG4J2}
+ *
+ * @param logSystem the logSystem to set
*/
- public static <K, V> GroupCacheAccess<K, V> getGroupCacheInstance( final String region, final ICompositeCacheAttributes icca, final IElementAttributes eattr )
- throws CacheException
+ public static void setLogSystem(final String logSystem)
{
- final CompositeCache<GroupAttrName<K>, V> cache = getCacheManager().getCache( region, icca, eattr );
- return new GroupCacheAccess<>( cache );
+ LogManager.setLogSystem(logSystem);
+ }
+
+ /**
+ * Shut down the cache manager and set the instance to null
+ */
+ public static void shutdown()
+ {
+ synchronized ( JCS.class )
+ {
+ if ( cacheMgr != null && cacheMgr.isInitialized())
+ {
+ cacheMgr.shutDown();
+ }
+
+ cacheMgr = null;
+ }
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/AbstractCacheAccess.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/AbstractCacheAccess.java
index 374620df..3b36ebc8 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/AbstractCacheAccess.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/AbstractCacheAccess.java
@@ -79,20 +79,58 @@ public abstract class AbstractCacheAccess<K, V>
}
/**
- * This method is does not reset the attributes for items already in the cache. It could
- * potentially do this for items in memory, and maybe on disk (which would be slow) but not
- * remote items. Rather than have unpredictable behavior, this method just sets the default
- * attributes. Items subsequently put into the cache will use these defaults if they do not
- * specify specific attributes.
+ * Dispose this region. Flushes objects to and closes auxiliary caches. This is a shutdown
+ * command!
* <p>
- * @param attr the default attributes.
- * @throws CacheException if something goes wrong.
+ * To simply remove all elements from the region use clear().
*/
@Override
- public void setDefaultElementAttributes( final IElementAttributes attr )
+ public void dispose()
+ {
+ this.getCacheControl().dispose();
+ }
+
+ /**
+ * This instructs the memory cache to remove the <i>numberToFree</i> according to its eviction
+ * policy. For example, the LRUMemoryCache will remove the <i>numberToFree</i> least recently
+ * used items. These will be spooled to disk if a disk auxiliary is available.
+ * <p>
+ * @param numberToFree
+ * @return the number that were removed. if you ask to free 5, but there are only 3, you will
+ * get 3.
+ * @throws CacheException
+ */
+ @Override
+ public int freeMemoryElements( final int numberToFree )
throws CacheException
{
- this.getCacheControl().setElementAttributes( attr );
+ int numFreed = -1;
+ try
+ {
+ numFreed = this.getCacheControl().getMemoryCache().freeElements( numberToFree );
+ }
+ catch ( final IOException ioe )
+ {
+ final String message = "Failure freeing memory elements.";
+ throw new CacheException( message, ioe );
+ }
+ return numFreed;
+ }
+
+ /**
+ * Gets the ICompositeCacheAttributes of the cache region.
+ * <p>
+ * @return ICompositeCacheAttributes, the controllers config info, defined in the top section of
+ * a region definition.
+ */
+ @Override
+ public ICompositeCacheAttributes getCacheAttributes()
+ {
+ return this.getCacheControl().getCacheAttributes();
+ }
+
+ public CompositeCache<K, V> getCacheControl() {
+ return cacheControl;
}
/**
@@ -134,30 +172,6 @@ public abstract class AbstractCacheAccess<K, V>
return this.getCacheControl().getStats();
}
- /**
- * Dispose this region. Flushes objects to and closes auxiliary caches. This is a shutdown
- * command!
- * <p>
- * To simply remove all elements from the region use clear().
- */
- @Override
- public void dispose()
- {
- this.getCacheControl().dispose();
- }
-
- /**
- * Gets the ICompositeCacheAttributes of the cache region.
- * <p>
- * @return ICompositeCacheAttributes, the controllers config info, defined in the top section of
- * a region definition.
- */
- @Override
- public ICompositeCacheAttributes getCacheAttributes()
- {
- return this.getCacheControl().getCacheAttributes();
- }
-
/**
* Sets the ICompositeCacheAttributes of the cache region.
* <p>
@@ -170,34 +184,20 @@ public abstract class AbstractCacheAccess<K, V>
}
/**
- * This instructs the memory cache to remove the <i>numberToFree</i> according to its eviction
- * policy. For example, the LRUMemoryCache will remove the <i>numberToFree</i> least recently
- * used items. These will be spooled to disk if a disk auxiliary is available.
+ * This method is does not reset the attributes for items already in the cache. It could
+ * potentially do this for items in memory, and maybe on disk (which would be slow) but not
+ * remote items. Rather than have unpredictable behavior, this method just sets the default
+ * attributes. Items subsequently put into the cache will use these defaults if they do not
+ * specify specific attributes.
* <p>
- * @param numberToFree
- * @return the number that were removed. if you ask to free 5, but there are only 3, you will
- * get 3.
- * @throws CacheException
+ * @param attr the default attributes.
+ * @throws CacheException if something goes wrong.
*/
@Override
- public int freeMemoryElements( final int numberToFree )
+ public void setDefaultElementAttributes( final IElementAttributes attr )
throws CacheException
{
- int numFreed = -1;
- try
- {
- numFreed = this.getCacheControl().getMemoryCache().freeElements( numberToFree );
- }
- catch ( final IOException ioe )
- {
- final String message = "Failure freeing memory elements.";
- throw new CacheException( message, ioe );
- }
- return numFreed;
- }
-
- public CompositeCache<K, V> getCacheControl() {
- return cacheControl;
+ this.getCacheControl().setElementAttributes( attr );
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/CacheAccess.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/CacheAccess.java
index 3b0afce1..5009fbc1 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/CacheAccess.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/CacheAccess.java
@@ -99,36 +99,6 @@ public class CacheAccess<K, V>
return value;
}
- /**
- * Retrieve matching objects from the cache region this instance provides access to.
- * <p>
- * @param pattern - a key pattern for the objects stored
- * @return A map of key to values. These are stripped from the wrapper.
- */
- @Override
- public Map<K, V> getMatching( final String pattern )
- {
- final Map<K, V> unwrappedResults;
-
- final Map<K, ICacheElement<K, V>> wrappedResults = this.getCacheControl().getMatching( pattern );
-
- if ( wrappedResults == null )
- {
- unwrappedResults = new HashMap<>();
- }
- else
- {
- unwrappedResults = wrappedResults.entrySet()
- .stream()
- .filter(entry -> entry.getValue() != null)
- .collect(Collectors.toMap(
- Entry::getKey,
- entry -> entry.getValue().getVal()));
- }
-
- return unwrappedResults;
- }
-
/**
* This method returns the ICacheElement<K, V> wrapper which provides access to element info and other
* attributes.
@@ -173,6 +143,61 @@ public class CacheAccess<K, V>
return this.getCacheControl().getMultiple( names );
}
+ /**
+ * GetElementAttributes will return an attribute object describing the current attributes
+ * associated with the object name. The name object must override the Object.equals and
+ * Object.hashCode methods.
+ * <p>
+ * @param name Key of object to get attributes for
+ * @return Attributes for the object, null if object not in cache
+ */
+ @Override
+ public IElementAttributes getElementAttributes( final K name ) throws CacheException
+ {
+ IElementAttributes attr = null;
+
+ try
+ {
+ attr = this.getCacheControl().getElementAttributes( name );
+ }
+ catch ( final IOException ioe )
+ {
+ throw new CacheException("Failure getting element attributes", ioe);
+ }
+
+ return attr;
+ }
+
+ /**
+ * Retrieve matching objects from the cache region this instance provides access to.
+ * <p>
+ * @param pattern - a key pattern for the objects stored
+ * @return A map of key to values. These are stripped from the wrapper.
+ */
+ @Override
+ public Map<K, V> getMatching( final String pattern )
+ {
+ final Map<K, V> unwrappedResults;
+
+ final Map<K, ICacheElement<K, V>> wrappedResults = this.getCacheControl().getMatching( pattern );
+
+ if ( wrappedResults == null )
+ {
+ unwrappedResults = new HashMap<>();
+ }
+ else
+ {
+ unwrappedResults = wrappedResults.entrySet()
+ .stream()
+ .filter(entry -> entry.getValue() != null)
+ .collect(Collectors.toMap(
+ Entry::getKey,
+ entry -> entry.getValue().getVal()));
+ }
+
+ return unwrappedResults;
+ }
+
/**
* Gets multiple elements from the cache based on a set of cache keys.
* <p>
@@ -196,27 +221,6 @@ public class CacheAccess<K, V>
return this.getCacheControl().getMatching( pattern );
}
- /**
- * Place a new object in the cache, associated with key name. If there is currently an object
- * associated with name in the region an ObjectExistsException is thrown. Names are scoped to a
- * region so they must be unique within the region they are placed.
- * <p>
- * @param key Key object will be stored with
- * @param value Object to store
- * @throws CacheException and ObjectExistsException is thrown if the item is already in the
- * cache.
- */
- @Override
- public void putSafe( final K key, final V value )
- {
- if ( this.getCacheControl().get( key ) != null )
- {
- throw new ObjectExistsException( "putSafe failed. Object exists in the cache for key [" + key
- + "]. Remove first or use a non-safe put to override the value." );
- }
- put( key, value );
- }
-
/**
* Place a new object in the cache, associated with key name. If there is currently an object
* associated with name in the region it is replaced. Names are scoped to a region so they must
@@ -269,6 +273,27 @@ public class CacheAccess<K, V>
}
}
+ /**
+ * Place a new object in the cache, associated with key name. If there is currently an object
+ * associated with name in the region an ObjectExistsException is thrown. Names are scoped to a
+ * region so they must be unique within the region they are placed.
+ * <p>
+ * @param key Key object will be stored with
+ * @param value Object to store
+ * @throws CacheException and ObjectExistsException is thrown if the item is already in the
+ * cache.
+ */
+ @Override
+ public void putSafe( final K key, final V value )
+ {
+ if ( this.getCacheControl().get( key ) != null )
+ {
+ throw new ObjectExistsException( "putSafe failed. Object exists in the cache for key [" + key
+ + "]. Remove first or use a non-safe put to override the value." );
+ }
+ put( key, value );
+ }
+
/**
* Removes a single item by name.
* <p>
@@ -305,29 +330,4 @@ public class CacheAccess<K, V>
put( element.getKey(), element.getVal(), attr );
}
-
- /**
- * GetElementAttributes will return an attribute object describing the current attributes
- * associated with the object name. The name object must override the Object.equals and
- * Object.hashCode methods.
- * <p>
- * @param name Key of object to get attributes for
- * @return Attributes for the object, null if object not in cache
- */
- @Override
- public IElementAttributes getElementAttributes( final K name ) throws CacheException
- {
- IElementAttributes attr = null;
-
- try
- {
- attr = this.getCacheControl().getElementAttributes( name );
- }
- catch ( final IOException ioe )
- {
- throw new CacheException("Failure getting element attributes", ioe);
- }
-
- return attr;
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/GroupCacheAccess.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/GroupCacheAccess.java
index 7d425734..45bc4982 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/GroupCacheAccess.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/GroupCacheAccess.java
@@ -79,6 +79,49 @@ public class GroupCacheAccess<K, V>
return new GroupAttrName<>( gid, name );
}
+ /**
+ * Gets the set of keys of objects currently in the group.
+ * <p>
+ * @param group
+ * @return A Set of keys.
+ */
+ @Override
+ public Set<K> getGroupKeys( final String group )
+ {
+ final GroupId groupId = new GroupId( this.getCacheControl().getCacheName(), group );
+
+ return this.getCacheControl().getKeySet()
+ .stream()
+ .filter(gan -> gan.groupId.equals(groupId))
+ .map(gan -> gan.attrName)
+ .collect(Collectors.toSet());
+ }
+
+ /**
+ * Gets the set of group names in the cache
+ * <p>
+ * @return A Set of group names.
+ */
+ public Set<String> getGroupNames()
+ {
+ return this.getCacheControl().getKeySet()
+ .stream()
+ .map(gan -> gan.groupId.groupName)
+ .collect(Collectors.toSet());
+ }
+
+ /**
+ * Invalidates a group: remove all the group members
+ * <p>
+ * @param group
+ * The name of the group to invalidate
+ */
+ @Override
+ public void invalidateGroup( final String group )
+ {
+ this.getCacheControl().remove(getGroupAttrName(group, null));
+ }
+
/**
* Allows the user to put an object into a group within a particular cache
* region. This method sets the object's attributes to the default for the
@@ -160,47 +203,4 @@ public class GroupCacheAccess<K, V>
final GroupAttrName<K> key = getGroupAttrName( group, name );
this.getCacheControl().remove( key );
}
-
- /**
- * Gets the set of keys of objects currently in the group.
- * <p>
- * @param group
- * @return A Set of keys.
- */
- @Override
- public Set<K> getGroupKeys( final String group )
- {
- final GroupId groupId = new GroupId( this.getCacheControl().getCacheName(), group );
-
- return this.getCacheControl().getKeySet()
- .stream()
- .filter(gan -> gan.groupId.equals(groupId))
- .map(gan -> gan.attrName)
- .collect(Collectors.toSet());
- }
-
- /**
- * Gets the set of group names in the cache
- * <p>
- * @return A Set of group names.
- */
- public Set<String> getGroupNames()
- {
- return this.getCacheControl().getKeySet()
- .stream()
- .map(gan -> gan.groupId.groupName)
- .collect(Collectors.toSet());
- }
-
- /**
- * Invalidates a group: remove all the group members
- * <p>
- * @param group
- * The name of the group to invalidate
- */
- @Override
- public void invalidateGroup( final String group )
- {
- this.getCacheControl().remove(getGroupAttrName(group, null));
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccess.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccess.java
index 3803f61a..17b9478a 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccess.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccess.java
@@ -51,45 +51,6 @@ public interface ICacheAccess<K, V>
*/
V get(K name, Supplier<V> supplier);
- /**
- * Retrieve matching objects from the cache region this instance provides access to.
- * <p>
- * @param pattern - a key pattern for the objects stored
- * @return A map of key to values. These are stripped from the wrapper.
- */
- Map<K, V> getMatching(String pattern);
-
- /**
- * Puts in cache if an item does not exist with the name in that region.
- * <p>
- * @param name
- * @param obj
- * @throws CacheException
- */
- void putSafe(K name, V obj)
- throws CacheException;
-
- /**
- * Puts and/or overrides an element with the name in that region.
- * <p>
- * @param name
- * @param obj
- * @throws CacheException
- */
- void put(K name, V obj)
- throws CacheException;
-
- /**
- * Description of the Method
- * <p>
- * @param name
- * @param obj
- * @param attr
- * @throws CacheException
- */
- void put(K name, V obj, IElementAttributes attr)
- throws CacheException;
-
/**
* This method returns the ICacheElement<K, V> wrapper which provides access to element info and other
* attributes.
@@ -127,6 +88,24 @@ public interface ICacheAccess<K, V>
*/
Map<K, ICacheElement<K, V>> getCacheElements(Set<K> names);
+ /**
+ * Gets the elementAttributes attribute of the ICacheAccess object
+ * <p>
+ * @param name
+ * @return The elementAttributes value
+ * @throws CacheException
+ */
+ IElementAttributes getElementAttributes(K name)
+ throws CacheException;
+
+ /**
+ * Retrieve matching objects from the cache region this instance provides access to.
+ * <p>
+ * @param pattern - a key pattern for the objects stored
+ * @return A map of key to values. These are stripped from the wrapper.
+ */
+ Map<K, V> getMatching(String pattern);
+
/**
* Gets multiple elements from the cache based on a set of cache keys.
* <p>
@@ -148,31 +127,52 @@ public interface ICacheAccess<K, V>
Map<K, ICacheElement<K, V>> getMatchingCacheElements(String pattern);
/**
- * Remove an object for this key if one exists, else do nothing.
+ * Puts and/or overrides an element with the name in that region.
* <p>
* @param name
+ * @param obj
* @throws CacheException
*/
- void remove(K name)
+ void put(K name, V obj)
throws CacheException;
/**
- * Reset the attributes on the object matching this key name.
+ * Description of the Method
* <p>
* @param name
- * @param attributes
+ * @param obj
+ * @param attr
* @throws CacheException
*/
- void resetElementAttributes(K name, IElementAttributes attributes)
+ void put(K name, V obj, IElementAttributes attr)
throws CacheException;
/**
- * Gets the elementAttributes attribute of the ICacheAccess object
+ * Puts in cache if an item does not exist with the name in that region.
* <p>
* @param name
- * @return The elementAttributes value
+ * @param obj
* @throws CacheException
*/
- IElementAttributes getElementAttributes(K name)
+ void putSafe(K name, V obj)
+ throws CacheException;
+
+ /**
+ * Remove an object for this key if one exists, else do nothing.
+ * <p>
+ * @param name
+ * @throws CacheException
+ */
+ void remove(K name)
+ throws CacheException;
+
+ /**
+ * Reset the attributes on the object matching this key name.
+ * <p>
+ * @param name
+ * @param attributes
+ * @throws CacheException
+ */
+ void resetElementAttributes(K name, IElementAttributes attributes)
throws CacheException;
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccessManagement.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccessManagement.java
index d3a9c180..d63fd242 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccessManagement.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/ICacheAccessManagement.java
@@ -29,6 +29,13 @@ import org.apache.commons.jcs3.engine.stats.behavior.ICacheStats;
*/
public interface ICacheAccessManagement
{
+ /**
+ * Removes all of the elements from a region.
+ * <p>
+ * @throws CacheException
+ */
+ void clear() throws CacheException;
+
/**
* Dispose this region. Flushes objects to and closes auxiliary caches. This is a shutdown
* command!
@@ -38,11 +45,24 @@ public interface ICacheAccessManagement
void dispose();
/**
- * Removes all of the elements from a region.
+ * This instructs the memory cache to remove the <i>numberToFree</i> according to its eviction
+ * policy. For example, the LRUMemoryCache will remove the <i>numberToFree</i> least recently
+ * used items. These will be spooled to disk if a disk auxiliary is available.
* <p>
+ * @param numberToFree
+ * @return the number that were removed. if you ask to free 5, but there are only 3, you will
+ * get 3.
* @throws CacheException
*/
- void clear() throws CacheException;
+ int freeMemoryElements( int numberToFree )
+ throws CacheException;
+
+ /**
+ * Gets the ICompositeCacheAttributes of the cache region
+ * <p>
+ * @return ICompositeCacheAttributes
+ */
+ ICompositeCacheAttributes getCacheAttributes();
/**
* GetElementAttributes will return an attribute object describing the current attributes
@@ -57,23 +77,18 @@ public interface ICacheAccessManagement
throws CacheException;
/**
- * This method is does not reset the attributes for items already in the cache. It could
- * potentially do this for items in memory, and maybe on disk (which would be slow) but not
- * remote items. Rather than have unpredictable behavior, this method just sets the default
- * attributes. Items subsequently put into the cache will use these defaults if they do not
- * specify specific attributes.
+ * This returns the ICacheStats object with information on this region and its auxiliaries.
* <p>
- * @param attr the default attributes.
- * @throws CacheException if something goes wrong.
+ * This data can be formatted as needed.
+ * <p>
+ * @return ICacheStats
*/
- void setDefaultElementAttributes( IElementAttributes attr ) throws CacheException;
+ ICacheStats getStatistics();
/**
- * Gets the ICompositeCacheAttributes of the cache region
- * <p>
- * @return ICompositeCacheAttributes
+ * @return A String version of the stats.
*/
- ICompositeCacheAttributes getCacheAttributes();
+ String getStats();
/**
* Sets the ICompositeCacheAttributes of the cache region
@@ -83,29 +98,14 @@ public interface ICacheAccessManagement
void setCacheAttributes( ICompositeCacheAttributes cattr );
/**
- * This instructs the memory cache to remove the <i>numberToFree</i> according to its eviction
- * policy. For example, the LRUMemoryCache will remove the <i>numberToFree</i> least recently
- * used items. These will be spooled to disk if a disk auxiliary is available.
- * <p>
- * @param numberToFree
- * @return the number that were removed. if you ask to free 5, but there are only 3, you will
- * get 3.
- * @throws CacheException
- */
- int freeMemoryElements( int numberToFree )
- throws CacheException;
-
- /**
- * This returns the ICacheStats object with information on this region and its auxiliaries.
- * <p>
- * This data can be formatted as needed.
+ * This method is does not reset the attributes for items already in the cache. It could
+ * potentially do this for items in memory, and maybe on disk (which would be slow) but not
+ * remote items. Rather than have unpredictable behavior, this method just sets the default
+ * attributes. Items subsequently put into the cache will use these defaults if they do not
+ * specify specific attributes.
* <p>
- * @return ICacheStats
- */
- ICacheStats getStatistics();
-
- /**
- * @return A String version of the stats.
+ * @param attr the default attributes.
+ * @throws CacheException if something goes wrong.
*/
- String getStats();
+ void setDefaultElementAttributes( IElementAttributes attr ) throws CacheException;
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/IGroupCacheAccess.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/IGroupCacheAccess.java
index ca09f8b9..abd72a19 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/IGroupCacheAccess.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/behavior/IGroupCacheAccess.java
@@ -41,6 +41,21 @@ public interface IGroupCacheAccess<K, V>
*/
V getFromGroup( K name, String group );
+ /**
+ * Gets the set of keys of objects currently in the group
+ * <p>
+ * @param group
+ * @return the set of group keys.
+ */
+ Set<K> getGroupKeys( String group );
+
+ /**
+ * Invalidates a group
+ * <p>
+ * @param group
+ */
+ void invalidateGroup( String group );
+
/**
* Puts an item in the cache associated with this group.
* <p>
@@ -71,19 +86,4 @@ public interface IGroupCacheAccess<K, V>
* @param group
*/
void removeFromGroup( K name, String group );
-
- /**
- * Gets the set of keys of objects currently in the group
- * <p>
- * @param group
- * @return the set of group keys.
- */
- Set<K> getGroupKeys( String group );
-
- /**
- * Invalidates a group
- * <p>
- * @param group
- */
- void invalidateGroup( String group );
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/exception/CacheException.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/exception/CacheException.java
index 9825b4b7..38441bc5 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/exception/CacheException.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/access/exception/CacheException.java
@@ -37,29 +37,29 @@ public class CacheException
/**
* Constructor for the CacheException object
- * @param nested a nested exception
+ * @param message the exception message
*/
- public CacheException( final Throwable nested )
+ public CacheException( final String message )
{
- super(nested);
+ super(message);
}
/**
* Constructor for the CacheException object
* @param message the exception message
+ * @param nested a nested exception
*/
- public CacheException( final String message )
+ public CacheException(final String message, final Throwable nested)
{
- super(message);
+ super(message, nested);
}
/**
* Constructor for the CacheException object
- * @param message the exception message
* @param nested a nested exception
*/
- public CacheException(final String message, final Throwable nested)
+ public CacheException( final Throwable nested )
{
- super(message, nested);
+ super(nested);
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheElementInfo.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheElementInfo.java
index a1266e53..2d191e22 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheElementInfo.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheElementInfo.java
@@ -63,27 +63,28 @@ public class CacheElementInfo
}
/**
- * @return a string representation of the key
+ * @return the time the object was created
*/
- public String getKey()
+ public String getCreateTime()
{
- return this.key;
+ return this.createTime;
}
/**
- * @return true if the item does not expire
+ * Ignored if isEternal
+ * @return how many seconds until this object expires.
*/
- public boolean isEternal()
+ public long getExpiresInSeconds()
{
- return this.eternal;
+ return this.expiresInSeconds;
}
/**
- * @return the time the object was created
+ * @return a string representation of the key
*/
- public String getCreateTime()
+ public String getKey()
{
- return this.createTime;
+ return this.key;
}
/**
@@ -96,12 +97,11 @@ public class CacheElementInfo
}
/**
- * Ignored if isEternal
- * @return how many seconds until this object expires.
+ * @return true if the item does not expire
*/
- public long getExpiresInSeconds()
+ public boolean isEternal()
{
- return this.expiresInSeconds;
+ return this.eternal;
}
/**
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheRegionInfo.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheRegionInfo.java
index 7956aee2..3bc45fbe 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheRegionInfo.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CacheRegionInfo.java
@@ -85,6 +85,14 @@ public class CacheRegionInfo
this.byteCount = byteCount;
}
+ /**
+ * @return total byte count
+ */
+ public long getByteCount()
+ {
+ return this.byteCount;
+ }
+
/**
* @return the cacheName
*/
@@ -101,14 +109,6 @@ public class CacheRegionInfo
return this.cacheSize;
}
- /**
- * @return a status string
- */
- public String getCacheStatus()
- {
- return this.cacheStatus;
- }
-
/**
* Return the statistics for the region.
* <p>
@@ -120,12 +120,12 @@ public class CacheRegionInfo
}
/**
- * @return the hitCountRam
- */
- public long getHitCountRam()
- {
- return hitCountRam;
- }
+ * @return a status string
+ */
+ public String getCacheStatus()
+ {
+ return this.cacheStatus;
+ }
/**
* @return the hitCountAux
@@ -136,11 +136,11 @@ public class CacheRegionInfo
}
/**
- * @return the missCountNotFound
+ * @return the hitCountRam
*/
- public long getMissCountNotFound()
+ public long getHitCountRam()
{
- return missCountNotFound;
+ return hitCountRam;
}
/**
@@ -152,12 +152,12 @@ public class CacheRegionInfo
}
/**
- * @return total byte count
- */
- public long getByteCount()
- {
- return this.byteCount;
- }
+ * @return the missCountNotFound
+ */
+ public long getMissCountNotFound()
+ {
+ return missCountNotFound;
+ }
/**
* @return string info on the region
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CountingOnlyOutputStream.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CountingOnlyOutputStream.java
index a08bdc7a..82fa5375 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CountingOnlyOutputStream.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/CountingOnlyOutputStream.java
@@ -31,6 +31,16 @@ public class CountingOnlyOutputStream
/** number of bytes passed through */
private int count; // TODO should this be long?
+ /**
+ * The number of bytes that have passed through this stream.
+ * <p>
+ * @return int
+ */
+ public int getCount()
+ {
+ return this.count;
+ }
+
/**
* count as we write.
* <p>
@@ -71,14 +81,4 @@ public class CountingOnlyOutputStream
{
this.count++;
}
-
- /**
- * The number of bytes that have passed through this stream.
- * <p>
- * @return int
- */
- public int getCount()
- {
- return this.count;
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSAdminBean.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSAdminBean.java
index ea0de214..48e31082 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSAdminBean.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSAdminBean.java
@@ -79,6 +79,41 @@ public class JCSAdminBean implements JCSJMXBean
}
/**
+ * Builds up data on every region.
+ * <p>
+ * TODO we need a most light weight method that does not count bytes. The byte counting can
+ * really swamp a server.
+ * @return List of CacheRegionInfo objects
+ */
+ @Override
+ public List<CacheRegionInfo> buildCacheInfo()
+ {
+ final TreeSet<String> cacheNames = new TreeSet<>(cacheHub.getCacheNames());
+
+ final LinkedList<CacheRegionInfo> cacheInfo = new LinkedList<>();
+
+ for (final String cacheName : cacheNames)
+ {
+ final CompositeCache<?, ?> cache = cacheHub.getCache( cacheName );
+
+ final CacheRegionInfo regionInfo = new CacheRegionInfo(
+ cache.getCacheName(),
+ cache.getSize(),
+ cache.getStatus().toString(),
+ cache.getStats(),
+ cache.getHitCountRam(),
+ cache.getHitCountAux(),
+ cache.getMissCountNotFound(),
+ cache.getMissCountExpired(),
+ getByteCount( cache ));
+
+ cacheInfo.add( regionInfo );
+ }
+
+ return cacheInfo;
+ }
+
+ /**
* Builds up info about each element in a region.
* <p>
* @param cacheName
@@ -121,56 +156,78 @@ public class JCSAdminBean implements JCSJMXBean
return records;
}
- /**
- * Builds up data on every region.
+
+ /**
+ * Clears all regions in the cache.
* <p>
- * TODO we need a most light weight method that does not count bytes. The byte counting can
- * really swamp a server.
- * @return List of CacheRegionInfo objects
+ * If this class is running within a remote cache server, clears all regions via the <code>RemoteCacheServer</code>
+ * API, so that removes will be broadcast to client machines. Otherwise clears all regions in the cache directly via
+ * the usual cache API.
*/
@Override
- public List<CacheRegionInfo> buildCacheInfo()
+ public void clearAllRegions() throws IOException
{
- final TreeSet<String> cacheNames = new TreeSet<>(cacheHub.getCacheNames());
-
- final LinkedList<CacheRegionInfo> cacheInfo = new LinkedList<>();
+ final RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
- for (final String cacheName : cacheNames)
+ if (remoteCacheServer == null)
{
- final CompositeCache<?, ?> cache = cacheHub.getCache( cacheName );
-
- final CacheRegionInfo regionInfo = new CacheRegionInfo(
- cache.getCacheName(),
- cache.getSize(),
- cache.getStatus().toString(),
- cache.getStats(),
- cache.getHitCountRam(),
- cache.getHitCountAux(),
- cache.getMissCountNotFound(),
- cache.getMissCountExpired(),
- getByteCount( cache ));
-
- cacheInfo.add( regionInfo );
+ // Not running in a remote cache server.
+ // Remove objects from the cache directly, as no need to broadcast removes to client machines...
+ for (final String name : cacheHub.getCacheNames())
+ {
+ cacheHub.getCache(name).removeAll();
+ }
+ }
+ else
+ {
+ // Running in a remote cache server.
+ // Remove objects via the RemoteCacheServer API, so that removes will be broadcast to client machines...
+ // Call remoteCacheServer.removeAll(String) for each cacheName...
+ for (final String name : cacheHub.getCacheNames())
+ {
+ remoteCacheServer.removeAll(name);
+ }
}
-
- return cacheInfo;
}
-
/**
- * Tries to estimate how much data is in a region. This is expensive. If there are any non serializable objects in
- * the region or an error occurs, suppresses exceptions and returns 0.
+ * Clears a particular cache region.
* <p>
- *
- * @return int The size of the region in bytes.
+ * If this class is running within a remote cache server, clears the region via the <code>RemoteCacheServer</code>
+ * API, so that removes will be broadcast to client machines. Otherwise clears the region directly via the usual
+ * cache API.
*/
- @Override
- public long getByteCount(final String cacheName)
- {
- return getByteCount(cacheHub.getCache(cacheName));
- }
+ @Override
+ public void clearRegion(final String cacheName) throws IOException
+ {
+ if (cacheName == null)
+ {
+ throw new IllegalArgumentException("The cache name specified was null.");
+ }
+ if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
+ {
+ // Not running in a remote cache server.
+ // Remove objects from the cache directly, as no need to broadcast removes to client machines...
+ cacheHub.getCache(cacheName).removeAll();
+ }
+ else
+ {
+ // Running in a remote cache server.
+ // Remove objects via the RemoteCacheServer API, so that removes will be broadcast to client machines...
+ try
+ {
+ // Call remoteCacheServer.removeAll(String)...
+ final RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
+ remoteCacheServer.removeAll(cacheName);
+ }
+ catch (final IOException e)
+ {
+ throw new IllegalStateException("Failed to remove all elements from cache region [" + cacheName + "]: " + e, e);
+ }
+ }
+ }
- /**
+ /**
* Tries to estimate how much data is in a region. This is expensive. If there are any non serializable objects in
* the region or an error occurs, suppresses exceptions and returns 0.
* <p>
@@ -243,74 +300,17 @@ public class JCSAdminBean implements JCSJMXBean
}
/**
- * Clears all regions in the cache.
- * <p>
- * If this class is running within a remote cache server, clears all regions via the <code>RemoteCacheServer</code>
- * API, so that removes will be broadcast to client machines. Otherwise clears all regions in the cache directly via
- * the usual cache API.
- */
- @Override
- public void clearAllRegions() throws IOException
- {
- final RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
-
- if (remoteCacheServer == null)
- {
- // Not running in a remote cache server.
- // Remove objects from the cache directly, as no need to broadcast removes to client machines...
- for (final String name : cacheHub.getCacheNames())
- {
- cacheHub.getCache(name).removeAll();
- }
- }
- else
- {
- // Running in a remote cache server.
- // Remove objects via the RemoteCacheServer API, so that removes will be broadcast to client machines...
- // Call remoteCacheServer.removeAll(String) for each cacheName...
- for (final String name : cacheHub.getCacheNames())
- {
- remoteCacheServer.removeAll(name);
- }
- }
- }
-
- /**
- * Clears a particular cache region.
+ * Tries to estimate how much data is in a region. This is expensive. If there are any non serializable objects in
+ * the region or an error occurs, suppresses exceptions and returns 0.
* <p>
- * If this class is running within a remote cache server, clears the region via the <code>RemoteCacheServer</code>
- * API, so that removes will be broadcast to client machines. Otherwise clears the region directly via the usual
- * cache API.
+ *
+ * @return int The size of the region in bytes.
*/
- @Override
- public void clearRegion(final String cacheName) throws IOException
- {
- if (cacheName == null)
- {
- throw new IllegalArgumentException("The cache name specified was null.");
- }
- if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
- {
- // Not running in a remote cache server.
- // Remove objects from the cache directly, as no need to broadcast removes to client machines...
- cacheHub.getCache(cacheName).removeAll();
- }
- else
- {
- // Running in a remote cache server.
- // Remove objects via the RemoteCacheServer API, so that removes will be broadcast to client machines...
- try
- {
- // Call remoteCacheServer.removeAll(String)...
- final RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
- remoteCacheServer.removeAll(cacheName);
- }
- catch (final IOException e)
- {
- throw new IllegalStateException("Failed to remove all elements from cache region [" + cacheName + "]: " + e, e);
- }
- }
- }
+ @Override
+ public long getByteCount(final String cacheName)
+ {
+ return getByteCount(cacheHub.getCache(cacheName));
+ }
/**
* Removes a particular item from a particular region.
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSJMXBean.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSJMXBean.java
index a686d424..aeedaed6 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSJMXBean.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/admin/JCSJMXBean.java
@@ -30,15 +30,6 @@ import javax.management.MXBean;
@MXBean
public interface JCSJMXBean
{
- /**
- * Builds up info about each element in a region.
- * <p>
- * @param cacheName
- * @return List of CacheElementInfo objects
- * @throws IOException
- */
- List<CacheElementInfo> buildElementInfo( String cacheName ) throws IOException;
-
/**
* Builds up data on every region.
* <p>
@@ -49,13 +40,13 @@ public interface JCSJMXBean
List<CacheRegionInfo> buildCacheInfo();
/**
- * Tries to estimate how much data is in a region. This is expensive. If there are any non serializable objects in
- * the region or an error occurs, suppresses exceptions and returns 0.
+ * Builds up info about each element in a region.
* <p>
- *
- * @return long The size of the region in bytes.
+ * @param cacheName
+ * @return List of CacheElementInfo objects
+ * @throws IOException
*/
- long getByteCount(String cacheName);
+ List<CacheElementInfo> buildElementInfo( String cacheName ) throws IOException;
/**
* Clears all regions in the cache.
@@ -75,6 +66,15 @@ public interface JCSJMXBean
*/
void clearRegion(String cacheName) throws IOException;
+ /**
+ * Tries to estimate how much data is in a region. This is expensive. If there are any non serializable objects in
+ * the region or an error occurs, suppresses exceptions and returns 0.
+ * <p>
+ *
+ * @return long The size of the region in bytes.
+ */
+ long getByteCount(String cacheName);
+
/**
* Removes a particular item from a particular region.
* <p>
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCache.java
index 619f6491..bf32bfae 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCache.java
@@ -48,47 +48,6 @@ public abstract class AbstractAuxiliaryCache<K, V>
/** Key matcher used by the getMatching API */
private IKeyMatcher<K> keyMatcher = new KeyMatcherPatternImpl<>();
- /**
- * Gets multiple items from the cache based on the given set of keys.
- *
- * @param keys
- * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
- * data in cache for any of these keys
- */
- protected Map<K, ICacheElement<K, V>> processGetMultiple(final Set<K> keys) throws IOException
- {
- if (keys != null)
- {
- return keys.stream()
- .map(key -> {
- try
- {
- return get(key);
- }
- catch (final IOException e)
- {
- return null;
- }
- })
- .filter(Objects::nonNull)
- .collect(Collectors.toMap(
- ICacheElement::getKey,
- element -> element));
- }
-
- return new HashMap<>();
- }
-
- /**
- * Gets the item from the cache.
- *
- * @param key
- * @return ICacheElement, a wrapper around the key, value, and attributes
- * @throws IOException
- */
- @Override
- public abstract ICacheElement<K, V> get( K key ) throws IOException;
-
/**
* Logs an event if an event logger is configured.
* <p>
@@ -135,16 +94,50 @@ public abstract class AbstractAuxiliaryCache<K, V>
}
/**
- * Logs an event if an event logger is configured.
+ * Gets the item from the cache.
+ *
+ * @param key
+ * @return ICacheElement, a wrapper around the key, value, and attributes
+ * @throws IOException
+ */
+ @Override
+ public abstract ICacheElement<K, V> get( K key ) throws IOException;
+
+ /**
+ * Allows it to be injected.
* <p>
- * @param cacheEvent
+ * @return cacheEventLogger
*/
- protected <T> void logICacheEvent( final ICacheEvent<T> cacheEvent )
+ public ICacheEventLogger getCacheEventLogger()
{
- if ( cacheEventLogger != null )
- {
- cacheEventLogger.logICacheEvent( cacheEvent );
- }
+ return this.cacheEventLogger;
+ }
+
+ /**
+ * Allows it to be injected.
+ * <p>
+ * @return elementSerializer
+ */
+ public IElementSerializer getElementSerializer()
+ {
+ return this.elementSerializer;
+ }
+
+ /**
+ * Gets the extra info for the event log.
+ * <p>
+ * @return IP, or disk location, etc.
+ */
+ public abstract String getEventLoggingExtraInfo();
+
+ /**
+ * Returns the key matcher used by get matching.
+ * <p>
+ * @return keyMatcher
+ */
+ public IKeyMatcher<K> getKeyMatcher()
+ {
+ return this.keyMatcher;
}
/**
@@ -178,31 +171,58 @@ public abstract class AbstractAuxiliaryCache<K, V>
}
/**
- * Gets the extra info for the event log.
+ * Logs an event if an event logger is configured.
* <p>
- * @return IP, or disk location, etc.
+ * @param cacheEvent
*/
- public abstract String getEventLoggingExtraInfo();
+ protected <T> void logICacheEvent( final ICacheEvent<T> cacheEvent )
+ {
+ if ( cacheEventLogger != null )
+ {
+ cacheEventLogger.logICacheEvent( cacheEvent );
+ }
+ }
/**
- * Allows it to be injected.
- * <p>
- * @param cacheEventLogger
+ * Gets multiple items from the cache based on the given set of keys.
+ *
+ * @param keys
+ * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
+ * data in cache for any of these keys
*/
- @Override
- public void setCacheEventLogger( final ICacheEventLogger cacheEventLogger )
+ protected Map<K, ICacheElement<K, V>> processGetMultiple(final Set<K> keys) throws IOException
{
- this.cacheEventLogger = cacheEventLogger;
+ if (keys != null)
+ {
+ return keys.stream()
+ .map(key -> {
+ try
+ {
+ return get(key);
+ }
+ catch (final IOException e)
+ {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toMap(
+ ICacheElement::getKey,
+ element -> element));
+ }
+
+ return new HashMap<>();
}
/**
* Allows it to be injected.
* <p>
- * @return cacheEventLogger
+ * @param cacheEventLogger
*/
- public ICacheEventLogger getCacheEventLogger()
+ @Override
+ public void setCacheEventLogger( final ICacheEventLogger cacheEventLogger )
{
- return this.cacheEventLogger;
+ this.cacheEventLogger = cacheEventLogger;
}
/**
@@ -222,16 +242,6 @@ public abstract class AbstractAuxiliaryCache<K, V>
}
}
- /**
- * Allows it to be injected.
- * <p>
- * @return elementSerializer
- */
- public IElementSerializer getElementSerializer()
- {
- return this.elementSerializer;
- }
-
/**
* Sets the key matcher used by get matching.
* <p>
@@ -245,14 +255,4 @@ public abstract class AbstractAuxiliaryCache<K, V>
this.keyMatcher = keyMatcher;
}
}
-
- /**
- * Returns the key matcher used by get matching.
- * <p>
- * @return keyMatcher
- */
- public IKeyMatcher<K> getKeyMatcher()
- {
- return this.keyMatcher;
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheAttributes.java
index d2a40b90..4d486c52 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheAttributes.java
@@ -43,12 +43,19 @@ public abstract class AbstractAuxiliaryCacheAttributes
private String eventQueuePoolName;
/**
- * @param name
+ * @see Object#clone()
*/
@Override
- public void setCacheName( final String name )
+ public AbstractAuxiliaryCacheAttributes clone()
{
- this.cacheName = name;
+ try
+ {
+ return (AbstractAuxiliaryCacheAttributes) super.clone();
+ }
+ catch (final CloneNotSupportedException e)
+ {
+ throw new IllegalStateException("Clone not supported. This should never happen.", e);
+ }
}
/**
@@ -63,45 +70,44 @@ public abstract class AbstractAuxiliaryCacheAttributes
}
/**
- * This is the name of the auxiliary in configuration file.
+ * Sets the pool name to use. If a pool is not found by this name, the thread pool manager will
+ * return a default configuration.
* <p>
- * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes#setName(String)
+ * @return name of thread pool to use for this auxiliary
*/
@Override
- public void setName( final String s )
+ public String getEventQueuePoolName()
{
- this.name = s;
+ return eventQueuePoolName;
}
/**
- * Gets the name attribute of the AuxiliaryCacheAttributes object
- * <p>
- * @return The name value
+ * @return SINGLE or POOLED
*/
@Override
- public String getName()
+ public ICacheEventQueue.QueueType getEventQueueType()
{
- return this.name;
+ return eventQueueType;
}
/**
- * SINGLE is the default. If you choose POOLED, the value of EventQueuePoolName will be used
+ * Gets the name attribute of the AuxiliaryCacheAttributes object
* <p>
- * @param queueType SINGLE or POOLED
+ * @return The name value
*/
@Override
- public void setEventQueueType( final ICacheEventQueue.QueueType queueType )
+ public String getName()
{
- this.eventQueueType = queueType;
+ return this.name;
}
/**
- * @return SINGLE or POOLED
+ * @param name
*/
@Override
- public ICacheEventQueue.QueueType getEventQueueType()
+ public void setCacheName( final String name )
{
- return eventQueueType;
+ this.cacheName = name;
}
/**
@@ -117,30 +123,24 @@ public abstract class AbstractAuxiliaryCacheAttributes
}
/**
- * Sets the pool name to use. If a pool is not found by this name, the thread pool manager will
- * return a default configuration.
+ * SINGLE is the default. If you choose POOLED, the value of EventQueuePoolName will be used
* <p>
- * @return name of thread pool to use for this auxiliary
+ * @param queueType SINGLE or POOLED
*/
@Override
- public String getEventQueuePoolName()
+ public void setEventQueueType( final ICacheEventQueue.QueueType queueType )
{
- return eventQueuePoolName;
+ this.eventQueueType = queueType;
}
/**
- * @see Object#clone()
+ * This is the name of the auxiliary in configuration file.
+ * <p>
+ * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes#setName(String)
*/
@Override
- public AbstractAuxiliaryCacheAttributes clone()
+ public void setName( final String s )
{
- try
- {
- return (AbstractAuxiliaryCacheAttributes) super.clone();
- }
- catch (final CloneNotSupportedException e)
- {
- throw new IllegalStateException("Clone not supported. This should never happen.", e);
- }
+ this.name = s;
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheEventLogging.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheEventLogging.java
index d7db07ce..8c79d456 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheEventLogging.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheEventLogging.java
@@ -38,31 +38,30 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
extends AbstractAuxiliaryCache<K, V>
{
/**
- * Puts an item into the cache.
+ * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
*
- * @param cacheElement
* @throws IOException
*/
@Override
- public void update( final ICacheElement<K, V> cacheElement )
+ public void dispose()
throws IOException
{
- updateWithEventLogging( cacheElement );
+ disposeWithEventLogging();
}
/**
- * Puts an item into the cache. Wrapped in logging.
+ * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
+ * Wraps the removeAll in event logs.
*
- * @param cacheElement
* @throws IOException
*/
- protected final void updateWithEventLogging( final ICacheElement<K, V> cacheElement )
+ protected final void disposeWithEventLogging()
throws IOException
{
- final ICacheEvent<K> cacheEvent = createICacheEvent( cacheElement, ICacheEventLogger.UPDATE_EVENT );
+ final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), "none", ICacheEventLogger.DISPOSE_EVENT );
try
{
- processUpdate( cacheElement );
+ processDispose();
}
finally
{
@@ -70,15 +69,6 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
}
}
- /**
- * Implementation of put.
- *
- * @param cacheElement
- * @throws IOException
- */
- protected abstract void processUpdate( ICacheElement<K, V> cacheElement )
- throws IOException;
-
/**
* Gets the item from the cache.
*
@@ -94,19 +84,41 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
}
/**
- * Gets the item from the cache. Wrapped in logging.
+ * Gets items from the cache matching the given pattern. Items from memory will replace those
+ * from remote sources.
*
- * @param key
- * @return ICacheElement, a wrapper around the key, value, and attributes
+ * This only works with string keys. It's too expensive to do a toString on every key.
+ *
+ * Auxiliaries will do their best to handle simple expressions. For instance, the JDBC disk
+ * cache will convert * to % and . to _
+ *
+ * @param pattern
+ * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
+ * data matching the pattern.
* @throws IOException
*/
- protected final ICacheElement<K, V> getWithEventLogging( final K key )
+ @Override
+ public Map<K, ICacheElement<K, V>> getMatching( final String pattern )
throws IOException
{
- final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.GET_EVENT );
+ return getMatchingWithEventLogging( pattern );
+ }
+
+ /**
+ * Gets matching items from the cache based on the given pattern.
+ *
+ * @param pattern
+ * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
+ * data matching the pattern.
+ * @throws IOException
+ */
+ protected final Map<K, ICacheElement<K, V>> getMatchingWithEventLogging( final String pattern )
+ throws IOException
+ {
+ final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), pattern, ICacheEventLogger.GETMATCHING_EVENT );
try
{
- return processGet( key );
+ return processGetMatching( pattern );
}
finally
{
@@ -114,16 +126,6 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
}
}
- /**
- * Implementation of get.
- *
- * @param key
- * @return ICacheElement, a wrapper around the key, value, and attributes
- * @throws IOException
- */
- protected abstract ICacheElement<K, V> processGet( K key )
- throws IOException;
-
/**
* Gets multiple items from the cache based on the given set of keys.
*
@@ -163,41 +165,19 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
}
/**
- * Gets items from the cache matching the given pattern. Items from memory will replace those
- * from remote sources.
- *
- * This only works with string keys. It's too expensive to do a toString on every key.
- *
- * Auxiliaries will do their best to handle simple expressions. For instance, the JDBC disk
- * cache will convert * to % and . to _
- *
- * @param pattern
- * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
- * data matching the pattern.
- * @throws IOException
- */
- @Override
- public Map<K, ICacheElement<K, V>> getMatching( final String pattern )
- throws IOException
- {
- return getMatchingWithEventLogging( pattern );
- }
-
- /**
- * Gets matching items from the cache based on the given pattern.
+ * Gets the item from the cache. Wrapped in logging.
*
- * @param pattern
- * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
- * data matching the pattern.
+ * @param key
+ * @return ICacheElement, a wrapper around the key, value, and attributes
* @throws IOException
*/
- protected final Map<K, ICacheElement<K, V>> getMatchingWithEventLogging( final String pattern )
+ protected final ICacheElement<K, V> getWithEventLogging( final K key )
throws IOException
{
- final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), pattern, ICacheEventLogger.GETMATCHING_EVENT );
+ final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.GET_EVENT );
try
{
- return processGetMatching( pattern );
+ return processGet( key );
}
finally
{
@@ -205,6 +185,24 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
}
}
+ /**
+ * Specific implementation of dispose.
+ *
+ * @throws IOException
+ */
+ protected abstract void processDispose()
+ throws IOException;
+
+ /**
+ * Implementation of get.
+ *
+ * @param key
+ * @return ICacheElement, a wrapper around the key, value, and attributes
+ * @throws IOException
+ */
+ protected abstract ICacheElement<K, V> processGet( K key )
+ throws IOException;
+
/**
* Implementation of getMatching.
*
@@ -217,49 +215,45 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
throws IOException;
/**
- * Removes the item from the cache. Wraps the remove in event logs.
+ * Specific implementation of remove.
*
* @param key
* @return boolean, whether or not the item was removed
* @throws IOException
*/
- @Override
- public boolean remove( final K key )
- throws IOException
- {
- return removeWithEventLogging( key );
- }
+ protected abstract boolean processRemove( K key )
+ throws IOException;
/**
- * Removes the item from the cache. Wraps the remove in event logs.
+ * Specific implementation of removeAll.
*
- * @param key
- * @return boolean, whether or not the item was removed
* @throws IOException
*/
- protected final boolean removeWithEventLogging( final K key )
- throws IOException
- {
- final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.REMOVE_EVENT );
- try
- {
- return processRemove( key );
- }
- finally
- {
- logICacheEvent( cacheEvent );
- }
- }
+ protected abstract void processRemoveAll()
+ throws IOException;
/**
- * Specific implementation of remove.
+ * Implementation of put.
+ *
+ * @param cacheElement
+ * @throws IOException
+ */
+ protected abstract void processUpdate( ICacheElement<K, V> cacheElement )
+ throws IOException;
+
+ /**
+ * Removes the item from the cache. Wraps the remove in event logs.
*
* @param key
* @return boolean, whether or not the item was removed
* @throws IOException
*/
- protected abstract boolean processRemove( K key )
- throws IOException;
+ @Override
+ public boolean remove( final K key )
+ throws IOException
+ {
+ return removeWithEventLogging( key );
+ }
/**
* Removes all from the region. Wraps the removeAll in event logs.
@@ -293,50 +287,56 @@ public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
}
/**
- * Specific implementation of removeAll.
+ * Removes the item from the cache. Wraps the remove in event logs.
*
+ * @param key
+ * @return boolean, whether or not the item was removed
* @throws IOException
*/
- protected abstract void processRemoveAll()
- throws IOException;
+ protected final boolean removeWithEventLogging( final K key )
+ throws IOException
+ {
+ final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.REMOVE_EVENT );
+ try
+ {
+ return processRemove( key );
+ }
+ finally
+ {
+ logICacheEvent( cacheEvent );
+ }
+ }
/**
- * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
+ * Puts an item into the cache.
*
+ * @param cacheElement
* @throws IOException
*/
@Override
- public void dispose()
+ public void update( final ICacheElement<K, V> cacheElement )
throws IOException
{
- disposeWithEventLogging();
+ updateWithEventLogging( cacheElement );
}
/**
- * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
- * Wraps the removeAll in event logs.
+ * Puts an item into the cache. Wrapped in logging.
*
+ * @param cacheElement
* @throws IOException
*/
- protected final void disposeWithEventLogging()
+ protected final void updateWithEventLogging( final ICacheElement<K, V> cacheElement )
throws IOException
{
- final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), "none", ICacheEventLogger.DISPOSE_EVENT );
+ final ICacheEvent<K> cacheEvent = createICacheEvent( cacheElement, ICacheEventLogger.UPDATE_EVENT );
try
{
- processDispose();
+ processUpdate( cacheElement );
}
finally
{
logICacheEvent( cacheEvent );
}
}
-
- /**
- * Specific implementation of dispose.
- *
- * @throws IOException
- */
- protected abstract void processDispose()
- throws IOException;
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheMonitor.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheMonitor.java
index bc62464a..a1c3c7b7 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheMonitor.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AbstractAuxiliaryCacheMonitor.java
@@ -36,12 +36,25 @@ import org.apache.commons.jcs3.log.LogManager;
*/
public abstract class AbstractAuxiliaryCacheMonitor extends Thread
{
- /** The logger */
- protected final Log log = LogManager.getLog( this.getClass() );
-
/** How long to wait between runs */
protected static long idlePeriod = 20 * 1000;
+ /**
+ * Configures the idle period between repairs.
+ * <p>
+ * @param idlePeriod The new idlePeriod value
+ */
+ public static void setIdlePeriod( final long idlePeriod )
+ {
+ if ( idlePeriod > AbstractAuxiliaryCacheMonitor.idlePeriod )
+ {
+ AbstractAuxiliaryCacheMonitor.idlePeriod = idlePeriod;
+ }
+ }
+
+ /** The logger */
+ protected final Log log = LogManager.getLog( this.getClass() );
+
/**
* Must make sure AbstractAuxiliaryCacheMonitor is started before any error can be detected!
*/
@@ -69,17 +82,14 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
}
/**
- * Configures the idle period between repairs.
- * <p>
- * @param idlePeriod The new idlePeriod value
+ * Clean up all resources before shutdown
*/
- public static void setIdlePeriod( final long idlePeriod )
- {
- if ( idlePeriod > AbstractAuxiliaryCacheMonitor.idlePeriod )
- {
- AbstractAuxiliaryCacheMonitor.idlePeriod = idlePeriod;
- }
- }
+ protected abstract void dispose();
+
+ /**
+ * do actual work
+ */
+ protected abstract void doWork();
/**
* Notifies the cache monitor that an error occurred, and kicks off the error recovery process.
@@ -103,30 +113,6 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
}
}
- // Trigger continuation of loop
- private void signalTrigger()
- {
- try
- {
- lock.lock();
- trigger.signal();
- }
- finally
- {
- lock.unlock();
- }
- }
-
- /**
- * Clean up all resources before shutdown
- */
- protected abstract void dispose();
-
- /**
- * do actual work
- */
- protected abstract void doWork();
-
/**
* Main processing method for the AbstractAuxiliaryCacheMonitor object
*/
@@ -194,4 +180,18 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
}
while ( true );
}
+
+ // Trigger continuation of loop
+ private void signalTrigger()
+ {
+ try
+ {
+ lock.lock();
+ trigger.signal();
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCache.java
index d18da8a7..34fb3cac 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCache.java
@@ -36,6 +36,14 @@ import org.apache.commons.jcs3.engine.stats.behavior.IStats;
public interface AuxiliaryCache<K, V>
extends ICache<K, V>
{
+ /**
+ * This returns the generic attributes for an auxiliary cache. Most implementations will cast
+ * this to a more specific type.
+ * <p>
+ * @return the attributes for the auxiliary cache
+ */
+ AuxiliaryCacheAttributes getAuxiliaryCacheAttributes();
+
/**
* Gets a set of the keys for all elements in the auxiliary cache.
* <p>
@@ -53,12 +61,11 @@ public interface AuxiliaryCache<K, V>
IStats getStatistics();
/**
- * This returns the generic attributes for an auxiliary cache. Most implementations will cast
- * this to a more specific type.
+ * Every Auxiliary must allow for the use of an event logger.
* <p>
- * @return the attributes for the auxiliary cache
+ * @param cacheEventLogger
*/
- AuxiliaryCacheAttributes getAuxiliaryCacheAttributes();
+ void setCacheEventLogger( ICacheEventLogger cacheEventLogger );
/**
* Allows you to inject a custom serializer. A good example would be a compressing standard
@@ -67,11 +74,4 @@ public interface AuxiliaryCache<K, V>
* @param elementSerializer
*/
void setElementSerializer( IElementSerializer elementSerializer );
-
- /**
- * Every Auxiliary must allow for the use of an event logger.
- * <p>
- * @param cacheEventLogger
- */
- void setCacheEventLogger( ICacheEventLogger cacheEventLogger );
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheAttributes.java
index d6640f12..a514eb8d 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheAttributes.java
@@ -31,11 +31,9 @@ public interface AuxiliaryCacheAttributes
extends Serializable, Cloneable
{
/**
- * Sets the name of the cache, referenced by the appropriate manager.
- * <p>
- * @param s The new cacheName value
+ * Clone object
*/
- void setCacheName( String s );
+ AuxiliaryCacheAttributes clone();
/**
* Gets the cacheName attribute of the AuxiliaryCacheAttributes object
@@ -45,11 +43,17 @@ public interface AuxiliaryCacheAttributes
String getCacheName();
/**
- * Name known by configurator
+ * Sets the pool name to use. If a pool is not found by this name, the thread pool manager will
+ * return a default configuration.
* <p>
- * @param s The new name value
+ * @return name of thread pool to use for this auxiliary
*/
- void setName( String s );
+ String getEventQueuePoolName();
+
+ /**
+ * @return SINGLE or POOLED
+ */
+ ICacheEventQueue.QueueType getEventQueueType();
/**
* Gets the name attribute of the AuxiliaryCacheAttributes object
@@ -59,16 +63,11 @@ public interface AuxiliaryCacheAttributes
String getName();
/**
- * SINGLE is the default. If you choose POOLED, the value of EventQueuePoolName will be used
+ * Sets the name of the cache, referenced by the appropriate manager.
* <p>
- * @param s SINGLE or POOLED
- */
- void setEventQueueType( ICacheEventQueue.QueueType s );
-
- /**
- * @return SINGLE or POOLED
+ * @param s The new cacheName value
*/
- ICacheEventQueue.QueueType getEventQueueType();
+ void setCacheName( String s );
/**
* If you choose a POOLED event queue type, the value of EventQueuePoolName will be used. This
@@ -79,15 +78,16 @@ public interface AuxiliaryCacheAttributes
void setEventQueuePoolName( String s );
/**
- * Sets the pool name to use. If a pool is not found by this name, the thread pool manager will
- * return a default configuration.
+ * SINGLE is the default. If you choose POOLED, the value of EventQueuePoolName will be used
* <p>
- * @return name of thread pool to use for this auxiliary
+ * @param s SINGLE or POOLED
*/
- String getEventQueuePoolName();
+ void setEventQueueType( ICacheEventQueue.QueueType s );
/**
- * Clone object
+ * Name known by configurator
+ * <p>
+ * @param s The new name value
*/
- AuxiliaryCacheAttributes clone();
+ void setName( String s );
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheFactory.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheFactory.java
index 52bffcda..7445da96 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheFactory.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/AuxiliaryCacheFactory.java
@@ -45,27 +45,27 @@ public interface AuxiliaryCacheFactory
ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
throws Exception;
- /**
- * Initialize this factory
- */
- default void initialize() { /* empty */ }
-
/**
* Dispose of this factory, clean up shared resources
*/
default void dispose() { /* empty */ }
/**
- * Sets the name attribute of the AuxiliaryCacheFactory object
+ * Gets the name attribute of the AuxiliaryCacheFactory object
*
- * @param s The new name value
+ * @return The name value
*/
- void setName( String s );
+ String getName();
/**
- * Gets the name attribute of the AuxiliaryCacheFactory object
+ * Initialize this factory
+ */
+ default void initialize() { /* empty */ }
+
+ /**
+ * Sets the name attribute of the AuxiliaryCacheFactory object
*
- * @return The name value
+ * @param s The new name value
*/
- String getName();
+ void setName( String s );
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCache.java
index c602fae7..6642996e 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCache.java
@@ -62,6 +62,160 @@ import org.apache.commons.jcs3.utils.struct.LRUMap;
public abstract class AbstractDiskCache<K, V>
extends AbstractAuxiliaryCacheEventLogging<K, V>
{
+ /**
+ * Cache that implements the CacheListener interface, and calls appropriate methods in its
+ * parent class.
+ */
+ protected class MyCacheListener
+ implements ICacheListener<K, V>
+ {
+ /** Id of the listener */
+ private long listenerId;
+
+ /**
+ * @return cacheElement.getElementAttributes();
+ * @throws IOException
+ * @see ICacheListener#getListenerId
+ */
+ @Override
+ public long getListenerId()
+ throws IOException
+ {
+ return this.listenerId;
+ }
+
+ /**
+ * @param cacheName
+ * @throws IOException
+ * @see ICacheListener#handleDispose
+ */
+ @Override
+ public void handleDispose( final String cacheName )
+ throws IOException
+ {
+ if (alive.get())
+ {
+ doDispose();
+ }
+ }
+
+ /**
+ * @param element
+ * @throws IOException
+ * @see ICacheListener#handlePut NOTE: This checks if the element is a puratory element and
+ * behaves differently depending. However since we have control over how elements are
+ * added to the cache event queue, that may not be needed ( they are always
+ * PurgatoryElements ).
+ */
+ @Override
+ public void handlePut( ICacheElement<K, V> element )
+ throws IOException
+ {
+ if (alive.get())
+ {
+ // If the element is a PurgatoryElement<K, V> we must check to see
+ // if it is still spoolable, and remove it from purgatory.
+ if ( element instanceof PurgatoryElement )
+ {
+ final PurgatoryElement<K, V> pe = (PurgatoryElement<K, V>) element;
+
+ synchronized ( pe.getCacheElement() )
+ {
+ // TODO consider a timeout.
+ // we need this so that we can have multiple update
+ // threads and still have removeAll requests come in that
+ // always win
+ removeAllLock.readLock().lock();
+
+ try
+ {
+ // If the element has already been removed from
+ // purgatory do nothing
+ if (!purgatory.containsKey(pe.getKey()))
+ {
+ return;
+ }
+
+ element = pe.getCacheElement();
+
+ // If the element is still eligible, spool it.
+ if ( pe.isSpoolable() )
+ {
+ doUpdate( element );
+ }
+ }
+ finally
+ {
+ removeAllLock.readLock().unlock();
+ }
+
+ // After the update has completed, it is safe to
+ // remove the element from purgatory.
+ purgatory.remove( element.getKey() );
+ }
+ }
+ else
+ {
+ // call the child's implementation
+ doUpdate( element );
+ }
+ }
+ else
+ {
+ /*
+ * The cache is not alive, hence the element should be removed from purgatory. All
+ * elements should be removed eventually. Perhaps, the alive check should have been
+ * done before it went in the queue. This block handles the case where the disk
+ * cache fails during normal operations.
+ */
+ purgatory.remove( element.getKey() );
+ }
+ }
+
+ /**
+ * @param cacheName
+ * @param key
+ * @throws IOException
+ * @see ICacheListener#handleRemove
+ */
+ @Override
+ public void handleRemove( final String cacheName, final K key )
+ throws IOException
+ {
+ if (alive.get() && doRemove( key ) )
+ {
+ log.debug( "Element removed, key: " + key );
+ }
+ }
+
+ /**
+ * @param cacheName
+ * @throws IOException
+ * @see ICacheListener#handleRemoveAll
+ */
+ @Override
+ public void handleRemoveAll( final String cacheName )
+ throws IOException
+ {
+ if (alive.get())
+ {
+ doRemoveAll();
+ }
+ }
+
+ /**
+ * @param id
+ * @throws IOException
+ * @see ICacheListener#setListenerId
+ */
+ @Override
+ public void setListenerId( final long id )
+ throws IOException
+ {
+ this.listenerId = id;
+ }
+ }
+
/** The logger */
private static final Log log = LogManager.getLog( AbstractDiskCache.class );
@@ -96,14 +250,14 @@ public abstract class AbstractDiskCache<K, V>
/** DEBUG: Keeps a count of the number of purgatory hits for debug messages */
private int purgHits;
+ // ----------------------------------------------------------- constructors
+
/**
* We lock here, so that we cannot get an update after a remove all. an individual removal locks
* the item.
*/
private final ReentrantReadWriteLock removeAllLock = new ReentrantReadWriteLock();
- // ----------------------------------------------------------- constructors
-
/**
* Construct the abstract disk cache, create event queues and purgatory. Child classes should
* set the alive flag to true after they are initialized.
@@ -127,97 +281,132 @@ public abstract class AbstractDiskCache<K, V>
}
/**
- * @return true if the cache is alive
+ * Adds a dispose request to the disk cache.
+ *
+ * Disposal proceeds in several steps.
+ * <ol>
+ * <li>Prior to this call the Composite cache dumped the memory into the disk cache. If it is
+ * large then we need to wait for the event queue to finish.</li>
+ * <li>Wait until the event queue is empty of until the configured ShutdownSpoolTimeLimit is
+ * reached.</li>
+ * <li>Call doDispose on the concrete impl.</li>
+ * </ol>
+ * @throws IOException
*/
- public boolean isAlive()
+ @Override
+ public final void dispose()
+ throws IOException
{
- return alive.get();
- }
+ log.info( "In dispose, destroying event queue." );
- /**
- * @param alive set the alive status
- */
- public void setAlive(final boolean alive)
- {
- this.alive.set(alive);
+ // wait for dispose and then quit if not done.
+ cacheEventQueue.destroy(this.diskCacheAttributes.getShutdownSpoolTimeLimit());
+
+ // Invoke any implementation specific disposal code
+ // need to handle the disposal first.
+ doDispose();
+
+ alive.set(false);
}
/**
- * Purgatory size of -1 means to use a HashMap with no size limit. Anything greater will use an
- * LRU map of some sort.
+ * Dispose of the persistent store. Note that disposal of purgatory and setting alive to false
+ * does NOT need to be done by this method.
*
- * TODO Currently setting this to 0 will cause nothing to be put to disk, since it will assume
- * that if an item is not in purgatory, then it must have been plucked. We should make 0
- * work, a way to not use purgatory.
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
+ * abstract process* methods. The children implement the process methods.
+ *
+ * @throws IOException
*/
- private void initPurgatory()
+ protected final void doDispose()
+ throws IOException
{
- // we need this so we can stop the updates from happening after a
- // remove all
- removeAllLock.writeLock().lock();
-
- try
- {
- synchronized (this)
- {
- if ( diskCacheAttributes.getMaxPurgatorySize() >= 0 )
- {
- purgatory = Collections.synchronizedMap(
- new LRUMap<>( diskCacheAttributes.getMaxPurgatorySize()));
- }
- else
- {
- purgatory = new ConcurrentHashMap<>();
- }
- }
- }
- finally
- {
- removeAllLock.writeLock().unlock();
- }
+ super.disposeWithEventLogging();
}
// ------------------------------------------------------- interface ICache
/**
- * Adds the provided element to the cache. Element will be added to purgatory, and then queued
- * for later writing to the serialized storage mechanism.
+ * Gets a value from the persistent store.
*
- * An update results in a put event being created. The put event will call the handlePut method
- * defined here. The handlePut method calls the implemented doPut on the child.
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
+ * abstract process* methods. The children implement the process methods.
*
- * @param cacheElement
+ * @param key Key to locate value for.
+ * @return An object matching key, or null.
* @throws IOException
- * @see org.apache.commons.jcs3.engine.behavior.ICache#update
*/
- @Override
- public final void update( final ICacheElement<K, V> cacheElement )
+ protected final ICacheElement<K, V> doGet( final K key )
throws IOException
{
- log.debug( "Putting element in purgatory, cacheName: {0}, key: {1}",
- () -> cacheName, cacheElement::getKey);
-
- try
- {
- // Wrap the CacheElement in a PurgatoryElement
- final PurgatoryElement<K, V> pe = new PurgatoryElement<>( cacheElement );
+ return super.getWithEventLogging( key );
+ }
- // Indicates the element is eligible to be spooled to disk,
- // this will remain true unless the item is pulled back into
- // memory.
- pe.setSpoolable( true );
+ /**
+ * Gets a value from the persistent store.
+ *
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
+ * abstract process* methods. The children implement the process methods.
+ *
+ * @param pattern Used to match keys.
+ * @return A map of matches..
+ * @throws IOException
+ */
+ protected final Map<K, ICacheElement<K, V>> doGetMatching( final String pattern )
+ throws IOException
+ {
+ return super.getMatchingWithEventLogging( pattern );
+ }
- // Add the element to purgatory
- purgatory.put( pe.getKey(), pe );
+ /**
+ * Remove an object from the persistent store if found.
+ *
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
+ * abstract process* methods. The children implement the process methods.
+ *
+ * @param key Key of object to remove.
+ * @return whether or no the item was present when removed
+ * @throws IOException
+ */
+ protected final boolean doRemove( final K key )
+ throws IOException
+ {
+ return super.removeWithEventLogging( key );
+ }
- // Queue element for serialization
- cacheEventQueue.addPutEvent( pe );
- }
- catch ( final IOException ex )
- {
- log.error( "Problem adding put event to queue.", ex );
- cacheEventQueue.destroy();
- }
+ /**
+ * Remove all objects from the persistent store.
+ *
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
+ * abstract process* methods. The children implement the process methods.
+ *
+ * @throws IOException
+ */
+ protected final void doRemoveAll()
+ throws IOException
+ {
+ super.removeAllWithEventLogging();
+ }
+
+ /**
+ * Add a cache element to the persistent store.
+ *
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
+ * abstract process* methods. The children implement the process methods.
+ *
+ * @param cacheElement
+ * @throws IOException
+ */
+ protected final void doUpdate( final ICacheElement<K, V> cacheElement )
+ throws IOException
+ {
+ super.updateWithEventLogging( cacheElement );
}
/**
@@ -284,6 +473,52 @@ public abstract class AbstractDiskCache<K, V>
return null;
}
+ /**
+ * @return the region name.
+ * @see ICache#getCacheName
+ */
+ @Override
+ public String getCacheName()
+ {
+ return cacheName;
+ }
+
+ /**
+ * @see org.apache.commons.jcs3.engine.behavior.ICacheType#getCacheType
+ * @return Always returns DISK_CACHE since subclasses should all be of that type.
+ */
+ @Override
+ public CacheType getCacheType()
+ {
+ return CacheType.DISK_CACHE;
+ }
+
+ /**
+ * This is used by the event logging.
+ *
+ * @return the location of the disk, either path or ip.
+ */
+ protected abstract String getDiskLocation();
+
+ /**
+ * Gets the extra info for the event log.
+ *
+ * @return disk location
+ */
+ @Override
+ public String getEventLoggingExtraInfo()
+ {
+ return getDiskLocation();
+ }
+
+ /**
+ * The keys in the cache.
+ *
+ * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getKeySet()
+ */
+ @Override
+ public abstract Set<K> getKeySet() throws IOException;
+
/**
* Gets items from the cache matching the given pattern. Items from memory will replace those
* from remote sources.
@@ -319,12 +554,111 @@ public abstract class AbstractDiskCache<K, V>
}
/**
- * The keys in the cache.
+ * Size cannot be determined without knowledge of the cache implementation, so subclasses will
+ * need to implement this method.
*
- * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getKeySet()
+ * @return the number of items.
+ * @see ICache#getSize
*/
@Override
- public abstract Set<K> getKeySet() throws IOException;
+ public abstract int getSize();
+
+ /**
+ * Returns semi-structured data.
+ *
+ * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getStatistics()
+ */
+ @Override
+ public IStats getStatistics()
+ {
+ final IStats stats = new Stats();
+ stats.setTypeName( "Abstract Disk Cache" );
+
+ final ArrayList<IStatElement<?>> elems = new ArrayList<>();
+
+ elems.add(new StatElement<>( "Purgatory Hits", Integer.valueOf(purgHits) ) );
+ elems.add(new StatElement<>( "Purgatory Size", Integer.valueOf(purgatory.size()) ) );
+
+ // get the stats from the event queue too
+ final IStats eqStats = this.cacheEventQueue.getStatistics();
+ elems.addAll(eqStats.getStatElements());
+
+ stats.setStatElements( elems );
+
+ return stats;
+ }
+
+ /**
+ * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
+ * methods call the *WithEventLogging method on the super. The *WithEventLogging methods call
+ * the abstract process* methods. The children implement the process methods.
+ *
+ * For example, doGet calls getWithEventLogging, which calls processGet
+ */
+
+ /**
+ * Gets basic stats for the abstract disk cache.
+ *
+ * @return String
+ */
+ @Override
+ public String getStats()
+ {
+ return getStatistics().toString();
+ }
+
+ /**
+ * @return the status -- alive or disposed from CacheConstants
+ * @see ICache#getStatus
+ */
+ @Override
+ public CacheStatus getStatus()
+ {
+ return alive.get() ? CacheStatus.ALIVE : CacheStatus.DISPOSED;
+ }
+
+ /**
+ * Purgatory size of -1 means to use a HashMap with no size limit. Anything greater will use an
+ * LRU map of some sort.
+ *
+ * TODO Currently setting this to 0 will cause nothing to be put to disk, since it will assume
+ * that if an item is not in purgatory, then it must have been plucked. We should make 0
+ * work, a way to not use purgatory.
+ */
+ private void initPurgatory()
+ {
+ // we need this so we can stop the updates from happening after a
+ // remove all
+ removeAllLock.writeLock().lock();
+
+ try
+ {
+ synchronized (this)
+ {
+ if ( diskCacheAttributes.getMaxPurgatorySize() >= 0 )
+ {
+ purgatory = Collections.synchronizedMap(
+ new LRUMap<>( diskCacheAttributes.getMaxPurgatorySize()));
+ }
+ else
+ {
+ purgatory = new ConcurrentHashMap<>();
+ }
+ }
+ }
+ finally
+ {
+ removeAllLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * @return true if the cache is alive
+ */
+ public boolean isAlive()
+ {
+ return alive.get();
+ }
/**
* Removes are not queued. A call to remove is immediate.
@@ -388,385 +722,51 @@ public abstract class AbstractDiskCache<K, V>
}
/**
- * Adds a dispose request to the disk cache.
+ * @param alive set the alive status
+ */
+ public void setAlive(final boolean alive)
+ {
+ this.alive.set(alive);
+ }
+
+ /**
+ * Adds the provided element to the cache. Element will be added to purgatory, and then queued
+ * for later writing to the serialized storage mechanism.
*
- * Disposal proceeds in several steps.
- * <ol>
- * <li>Prior to this call the Composite cache dumped the memory into the disk cache. If it is
- * large then we need to wait for the event queue to finish.</li>
- * <li>Wait until the event queue is empty of until the configured ShutdownSpoolTimeLimit is
- * reached.</li>
- * <li>Call doDispose on the concrete impl.</li>
- * </ol>
+ * An update results in a put event being created. The put event will call the handlePut method
+ * defined here. The handlePut method calls the implemented doPut on the child.
+ *
+ * @param cacheElement
* @throws IOException
+ * @see org.apache.commons.jcs3.engine.behavior.ICache#update
*/
@Override
- public final void dispose()
+ public final void update( final ICacheElement<K, V> cacheElement )
throws IOException
{
- log.info( "In dispose, destroying event queue." );
-
- // wait for dispose and then quit if not done.
- cacheEventQueue.destroy(this.diskCacheAttributes.getShutdownSpoolTimeLimit());
+ log.debug( "Putting element in purgatory, cacheName: {0}, key: {1}",
+ () -> cacheName, cacheElement::getKey);
- // Invoke any implementation specific disposal code
- // need to handle the disposal first.
- doDispose();
-
- alive.set(false);
- }
-
- /**
- * @return the region name.
- * @see ICache#getCacheName
- */
- @Override
- public String getCacheName()
- {
- return cacheName;
- }
-
- /**
- * Gets basic stats for the abstract disk cache.
- *
- * @return String
- */
- @Override
- public String getStats()
- {
- return getStatistics().toString();
- }
-
- /**
- * Returns semi-structured data.
- *
- * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getStatistics()
- */
- @Override
- public IStats getStatistics()
- {
- final IStats stats = new Stats();
- stats.setTypeName( "Abstract Disk Cache" );
-
- final ArrayList<IStatElement<?>> elems = new ArrayList<>();
-
- elems.add(new StatElement<>( "Purgatory Hits", Integer.valueOf(purgHits) ) );
- elems.add(new StatElement<>( "Purgatory Size", Integer.valueOf(purgatory.size()) ) );
-
- // get the stats from the event queue too
- final IStats eqStats = this.cacheEventQueue.getStatistics();
- elems.addAll(eqStats.getStatElements());
-
- stats.setStatElements( elems );
-
- return stats;
- }
-
- /**
- * @return the status -- alive or disposed from CacheConstants
- * @see ICache#getStatus
- */
- @Override
- public CacheStatus getStatus()
- {
- return alive.get() ? CacheStatus.ALIVE : CacheStatus.DISPOSED;
- }
-
- /**
- * Size cannot be determined without knowledge of the cache implementation, so subclasses will
- * need to implement this method.
- *
- * @return the number of items.
- * @see ICache#getSize
- */
- @Override
- public abstract int getSize();
-
- /**
- * @see org.apache.commons.jcs3.engine.behavior.ICacheType#getCacheType
- * @return Always returns DISK_CACHE since subclasses should all be of that type.
- */
- @Override
- public CacheType getCacheType()
- {
- return CacheType.DISK_CACHE;
- }
-
- /**
- * Cache that implements the CacheListener interface, and calls appropriate methods in its
- * parent class.
- */
- protected class MyCacheListener
- implements ICacheListener<K, V>
- {
- /** Id of the listener */
- private long listenerId;
-
- /**
- * @return cacheElement.getElementAttributes();
- * @throws IOException
- * @see ICacheListener#getListenerId
- */
- @Override
- public long getListenerId()
- throws IOException
- {
- return this.listenerId;
- }
-
- /**
- * @param id
- * @throws IOException
- * @see ICacheListener#setListenerId
- */
- @Override
- public void setListenerId( final long id )
- throws IOException
- {
- this.listenerId = id;
- }
-
- /**
- * @param element
- * @throws IOException
- * @see ICacheListener#handlePut NOTE: This checks if the element is a puratory element and
- * behaves differently depending. However since we have control over how elements are
- * added to the cache event queue, that may not be needed ( they are always
- * PurgatoryElements ).
- */
- @Override
- public void handlePut( ICacheElement<K, V> element )
- throws IOException
+ try
{
- if (alive.get())
- {
- // If the element is a PurgatoryElement<K, V> we must check to see
- // if it is still spoolable, and remove it from purgatory.
- if ( element instanceof PurgatoryElement )
- {
- final PurgatoryElement<K, V> pe = (PurgatoryElement<K, V>) element;
-
- synchronized ( pe.getCacheElement() )
- {
- // TODO consider a timeout.
- // we need this so that we can have multiple update
- // threads and still have removeAll requests come in that
- // always win
- removeAllLock.readLock().lock();
-
- try
- {
- // If the element has already been removed from
- // purgatory do nothing
- if (!purgatory.containsKey(pe.getKey()))
- {
- return;
- }
-
- element = pe.getCacheElement();
-
- // If the element is still eligible, spool it.
- if ( pe.isSpoolable() )
- {
- doUpdate( element );
- }
- }
- finally
- {
- removeAllLock.readLock().unlock();
- }
+ // Wrap the CacheElement in a PurgatoryElement
+ final PurgatoryElement<K, V> pe = new PurgatoryElement<>( cacheElement );
- // After the update has completed, it is safe to
- // remove the element from purgatory.
- purgatory.remove( element.getKey() );
- }
- }
- else
- {
- // call the child's implementation
- doUpdate( element );
- }
- }
- else
- {
- /*
- * The cache is not alive, hence the element should be removed from purgatory. All
- * elements should be removed eventually. Perhaps, the alive check should have been
- * done before it went in the queue. This block handles the case where the disk
- * cache fails during normal operations.
- */
- purgatory.remove( element.getKey() );
- }
- }
+ // Indicates the element is eligible to be spooled to disk,
+ // this will remain true unless the item is pulled back into
+ // memory.
+ pe.setSpoolable( true );
- /**
- * @param cacheName
- * @param key
- * @throws IOException
- * @see ICacheListener#handleRemove
- */
- @Override
- public void handleRemove( final String cacheName, final K key )
- throws IOException
- {
- if (alive.get() && doRemove( key ) )
- {
- log.debug( "Element removed, key: " + key );
- }
- }
+ // Add the element to purgatory
+ purgatory.put( pe.getKey(), pe );
- /**
- * @param cacheName
- * @throws IOException
- * @see ICacheListener#handleRemoveAll
- */
- @Override
- public void handleRemoveAll( final String cacheName )
- throws IOException
- {
- if (alive.get())
- {
- doRemoveAll();
- }
+ // Queue element for serialization
+ cacheEventQueue.addPutEvent( pe );
}
-
- /**
- * @param cacheName
- * @throws IOException
- * @see ICacheListener#handleDispose
- */
- @Override
- public void handleDispose( final String cacheName )
- throws IOException
+ catch ( final IOException ex )
{
- if (alive.get())
- {
- doDispose();
- }
+ log.error( "Problem adding put event to queue.", ex );
+ cacheEventQueue.destroy();
}
}
-
- /**
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *WithEventLogging method on the super. The *WithEventLogging methods call
- * the abstract process* methods. The children implement the process methods.
- *
- * For example, doGet calls getWithEventLogging, which calls processGet
- */
-
- /**
- * Gets a value from the persistent store.
- *
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
- *
- * @param key Key to locate value for.
- * @return An object matching key, or null.
- * @throws IOException
- */
- protected final ICacheElement<K, V> doGet( final K key )
- throws IOException
- {
- return super.getWithEventLogging( key );
- }
-
- /**
- * Gets a value from the persistent store.
- *
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
- *
- * @param pattern Used to match keys.
- * @return A map of matches..
- * @throws IOException
- */
- protected final Map<K, ICacheElement<K, V>> doGetMatching( final String pattern )
- throws IOException
- {
- return super.getMatchingWithEventLogging( pattern );
- }
-
- /**
- * Add a cache element to the persistent store.
- *
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
- *
- * @param cacheElement
- * @throws IOException
- */
- protected final void doUpdate( final ICacheElement<K, V> cacheElement )
- throws IOException
- {
- super.updateWithEventLogging( cacheElement );
- }
-
- /**
- * Remove an object from the persistent store if found.
- *
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
- *
- * @param key Key of object to remove.
- * @return whether or no the item was present when removed
- * @throws IOException
- */
- protected final boolean doRemove( final K key )
- throws IOException
- {
- return super.removeWithEventLogging( key );
- }
-
- /**
- * Remove all objects from the persistent store.
- *
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
- *
- * @throws IOException
- */
- protected final void doRemoveAll()
- throws IOException
- {
- super.removeAllWithEventLogging();
- }
-
- /**
- * Dispose of the persistent store. Note that disposal of purgatory and setting alive to false
- * does NOT need to be done by this method.
- *
- * Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *EventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
- *
- * @throws IOException
- */
- protected final void doDispose()
- throws IOException
- {
- super.disposeWithEventLogging();
- }
-
- /**
- * Gets the extra info for the event log.
- *
- * @return disk location
- */
- @Override
- public String getEventLoggingExtraInfo()
- {
- return getDiskLocation();
- }
-
- /**
- * This is used by the event logging.
- *
- * @return the location of the disk, either path or ip.
- */
- protected abstract String getDiskLocation();
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCacheAttributes.java
index b0ca8d67..a5d422c8 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/AbstractDiskCacheAttributes.java
@@ -37,6 +37,9 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
/** The logger */
private static final Log log = LogManager.getLog(AbstractDiskCacheAttributes.class);
+ /** Default amount of time to allow for key persistence on shutdown */
+ private static final int DEFAULT_shutdownSpoolTimeLimit = 60;
+
/** path to disk */
private File diskPath;
@@ -46,9 +49,6 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
/** default to 5000 */
private int maxPurgatorySize = MAX_PURGATORY_SIZE_DEFAULT;
- /** Default amount of time to allow for key persistence on shutdown */
- private static final int DEFAULT_shutdownSpoolTimeLimit = 60;
-
/**
* This default determines how long the shutdown will wait for the key spool and data defrag to
* finish.
@@ -58,17 +58,81 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
/** Type of disk limit: SIZE or COUNT */
private DiskLimitType diskLimitType = DiskLimitType.COUNT;
+ @Override
+ public DiskLimitType getDiskLimitType()
+ {
+ return diskLimitType;
+ }
+
/**
- * Sets the diskPath attribute of the DiskCacheAttributes object
+ * Gets the diskPath attribute of the attributes object
* <p>
*
- * @param path
- * The new diskPath value
+ * @return The diskPath value
*/
@Override
- public void setDiskPath(final String path)
+ public File getDiskPath()
{
- setDiskPath(new File(path));
+ return this.diskPath;
+ }
+
+ /**
+ * Gets the maxKeySize attribute of the DiskCacheAttributes object
+ * <p>
+ *
+ * @return The maxPurgatorySize value
+ */
+ @Override
+ public int getMaxPurgatorySize()
+ {
+ return maxPurgatorySize;
+ }
+
+ /**
+ * Gets the amount of time in seconds we will wait for elements to move to disk during shutdown
+ * for a particular region.
+ * <p>
+ *
+ * @return the time in seconds.
+ */
+ @Override
+ public int getShutdownSpoolTimeLimit()
+ {
+ return this.shutdownSpoolTimeLimit;
+ }
+
+ /**
+ * @return Returns the allowRemoveAll.
+ */
+ @Override
+ public boolean isAllowRemoveAll()
+ {
+ return allowRemoveAll;
+ }
+
+ /**
+ * @param allowRemoveAll
+ * The allowRemoveAll to set.
+ */
+ @Override
+ public void setAllowRemoveAll(final boolean allowRemoveAll)
+ {
+ this.allowRemoveAll = allowRemoveAll;
+ }
+
+ @Override
+ public void setDiskLimitType(final DiskLimitType diskLimitType)
+ {
+ this.diskLimitType = diskLimitType;
+ }
+
+ @Override
+ public void setDiskLimitTypeName(final String diskLimitTypeName)
+ {
+ if (diskLimitTypeName != null)
+ {
+ diskLimitType = DiskLimitType.valueOf(diskLimitTypeName.trim());
+ }
}
/**
@@ -94,27 +158,16 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
}
/**
- * Gets the diskPath attribute of the attributes object
- * <p>
- *
- * @return The diskPath value
- */
- @Override
- public File getDiskPath()
- {
- return this.diskPath;
- }
-
- /**
- * Gets the maxKeySize attribute of the DiskCacheAttributes object
+ * Sets the diskPath attribute of the DiskCacheAttributes object
* <p>
*
- * @return The maxPurgatorySize value
+ * @param path
+ * The new diskPath value
*/
@Override
- public int getMaxPurgatorySize()
+ public void setDiskPath(final String path)
{
- return maxPurgatorySize;
+ setDiskPath(new File(path));
}
/**
@@ -130,19 +183,6 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
this.maxPurgatorySize = maxPurgatorySize;
}
- /**
- * Gets the amount of time in seconds we will wait for elements to move to disk during shutdown
- * for a particular region.
- * <p>
- *
- * @return the time in seconds.
- */
- @Override
- public int getShutdownSpoolTimeLimit()
- {
- return this.shutdownSpoolTimeLimit;
- }
-
/**
* Sets the amount of time in seconds we will wait for elements to move to disk during shutdown
* for a particular region.
@@ -161,25 +201,6 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
this.shutdownSpoolTimeLimit = shutdownSpoolTimeLimit;
}
- /**
- * @param allowRemoveAll
- * The allowRemoveAll to set.
- */
- @Override
- public void setAllowRemoveAll(final boolean allowRemoveAll)
- {
- this.allowRemoveAll = allowRemoveAll;
- }
-
- /**
- * @return Returns the allowRemoveAll.
- */
- @Override
- public boolean isAllowRemoveAll()
- {
- return allowRemoveAll;
- }
-
/**
* Includes the common attributes for a debug message.
* <p>
@@ -197,25 +218,4 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
str.append("\n ShutdownSpoolTimeLimit = " + getShutdownSpoolTimeLimit());
return str.toString();
}
-
- @Override
- public void setDiskLimitType(final DiskLimitType diskLimitType)
- {
- this.diskLimitType = diskLimitType;
- }
-
- @Override
- public void setDiskLimitTypeName(final String diskLimitTypeName)
- {
- if (diskLimitTypeName != null)
- {
- diskLimitType = DiskLimitType.valueOf(diskLimitTypeName.trim());
- }
- }
-
- @Override
- public DiskLimitType getDiskLimitType()
- {
- return diskLimitType;
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/PurgatoryElement.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/PurgatoryElement.java
index f6a8cc34..bf914db7 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/PurgatoryElement.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/PurgatoryElement.java
@@ -53,23 +53,22 @@ public class PurgatoryElement<K, V>
}
/**
- * Gets the spoolable property.
- *
- * @return The spoolable value
- */
- public boolean isSpoolable()
- {
- return spoolable;
- }
-
- /**
- * Sets the spoolable property.
- *
- * @param spoolable The new spoolable value
+ * @param obj other object
+ * @return true if this object key equals the key of obj
*/
- public void setSpoolable( final boolean spoolable )
+ @Override
+ public boolean equals(final Object obj)
{
- this.spoolable = spoolable;
+ if (this == obj)
+ {
+ return true;
+ }
+ if (!(obj instanceof PurgatoryElement))
+ {
+ return false;
+ }
+ final PurgatoryElement<?,?> other = (PurgatoryElement<?,?>) obj;
+ return Objects.equals(getKey(), other.getKey());
}
/**
@@ -82,8 +81,6 @@ public class PurgatoryElement<K, V>
return cacheElement;
}
- // ------------------------------------------------ interface ICacheElement
-
/**
* @return cacheElement.getCacheName();
* @see ICacheElement#getCacheName
@@ -94,6 +91,18 @@ public class PurgatoryElement<K, V>
return cacheElement.getCacheName();
}
+ // ------------------------------------------------ interface ICacheElement
+
+ /**
+ * @return cacheElement.getElementAttributes();
+ * @see ICacheElement#getElementAttributes
+ */
+ @Override
+ public IElementAttributes getElementAttributes()
+ {
+ return cacheElement.getElementAttributes();
+ }
+
/**
* @return cacheElement.getKey();
* @see ICacheElement#getKey
@@ -115,51 +124,42 @@ public class PurgatoryElement<K, V>
}
/**
- * @return cacheElement.getElementAttributes();
- * @see ICacheElement#getElementAttributes
+ * @return a hash of the key only
*/
@Override
- public IElementAttributes getElementAttributes()
+ public int hashCode()
{
- return cacheElement.getElementAttributes();
+ return getKey().hashCode();
}
/**
- * @param attr
- * @see ICacheElement#setElementAttributes
+ * Gets the spoolable property.
+ *
+ * @return The spoolable value
*/
- @Override
- public void setElementAttributes( final IElementAttributes attr )
+ public boolean isSpoolable()
{
- cacheElement.setElementAttributes( attr );
+ return spoolable;
}
/**
- * @param obj other object
- * @return true if this object key equals the key of obj
+ * @param attr
+ * @see ICacheElement#setElementAttributes
*/
@Override
- public boolean equals(final Object obj)
+ public void setElementAttributes( final IElementAttributes attr )
{
- if (this == obj)
- {
- return true;
- }
- if (!(obj instanceof PurgatoryElement))
- {
- return false;
- }
- final PurgatoryElement<?,?> other = (PurgatoryElement<?,?>) obj;
- return Objects.equals(getKey(), other.getKey());
+ cacheElement.setElementAttributes( attr );
}
/**
- * @return a hash of the key only
+ * Sets the spoolable property.
+ *
+ * @param spoolable The new spoolable value
*/
- @Override
- public int hashCode()
+ public void setSpoolable( final boolean spoolable )
{
- return getKey().hashCode();
+ this.spoolable = spoolable;
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/behavior/IDiskCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/behavior/IDiskCacheAttributes.java
index 4e2c0973..c5395f0e 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/behavior/IDiskCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/behavior/IDiskCacheAttributes.java
@@ -43,12 +43,10 @@ public interface IDiskCacheAttributes
int MAX_PURGATORY_SIZE_DEFAULT = 5000;
/**
- * Sets the diskPath attribute of the IJISPCacheAttributes object
- * <p>
- * @param path
- * The new diskPath value
+ *
+ * @return active DiskLimitType
*/
- void setDiskPath( String path );
+ DiskLimitType getDiskLimitType();
/**
* Gets the diskPath attribute of the attributes object
@@ -64,14 +62,6 @@ public interface IDiskCacheAttributes
*/
int getMaxPurgatorySize();
- /**
- * Sets the maxPurgatorySize attribute of the DiskCacheAttributes object
- * <p>
- * @param maxPurgatorySize
- * The new maxPurgatorySize value
- */
- void setMaxPurgatorySize( int maxPurgatorySize );
-
/**
* Gets the amount of time in seconds we will wait for elements to move to
* disk during shutdown for a particular region.
@@ -80,19 +70,6 @@ public interface IDiskCacheAttributes
*/
int getShutdownSpoolTimeLimit();
- /**
- * Sets the amount of time in seconds we will wait for elements to move to
- * disk during shutdown for a particular region.
- * <p>
- * This is how long we give the event queue to empty.
- * <p>
- * The default is 60 seconds.
- * <p>
- * @param shutdownSpoolTimeLimit
- * the time in seconds
- */
- void setShutdownSpoolTimeLimit( int shutdownSpoolTimeLimit );
-
/**
* If this is true then remove all is not prohibited.
* <p>
@@ -124,8 +101,31 @@ public interface IDiskCacheAttributes
void setDiskLimitTypeName(String diskLimitTypeName);
/**
- *
- * @return active DiskLimitType
+ * Sets the diskPath attribute of the IJISPCacheAttributes object
+ * <p>
+ * @param path
+ * The new diskPath value
*/
- DiskLimitType getDiskLimitType();
+ void setDiskPath( String path );
+
+ /**
+ * Sets the maxPurgatorySize attribute of the DiskCacheAttributes object
+ * <p>
+ * @param maxPurgatorySize
+ * The new maxPurgatorySize value
+ */
+ void setMaxPurgatorySize( int maxPurgatorySize );
+
+ /**
+ * Sets the amount of time in seconds we will wait for elements to move to
+ * disk during shutdown for a particular region.
+ * <p>
+ * This is how long we give the event queue to empty.
+ * <p>
+ * The default is 60 seconds.
+ * <p>
+ * @param shutdownSpoolTimeLimit
+ * the time in seconds
+ */
+ void setShutdownSpoolTimeLimit( int shutdownSpoolTimeLimit );
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDisk.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDisk.java
index 564dca3f..98d16e73 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDisk.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDisk.java
@@ -152,71 +152,86 @@ public class BlockDisk implements AutoCloseable
}
/**
- * This writes an object to disk and returns the blocks it was stored in.
+ * Calculates the file offset for a particular block.
* <p>
- * The program flow is as follows:
- * <ol>
- * <li>Serialize the object.</li>
- * <li>Determine the number of blocks needed.</li>
- * <li>Look for free blocks in the emptyBlock list.</li>
- * <li>If there were not enough in the empty list. Take the nextBlock and increment it.</li>
- * <li>If the data will not fit in one block, create sub arrays.</li>
- * <li>Write the subarrays to disk.</li>
- * <li>If the process fails we should decrement the block count if we took from it.</li>
- * </ol>
- * @param object
- * @return the blocks we used.
- * @throws IOException
+ * @param block number
+ * @return the byte offset for this block in the file as a long
+ * @since 2.0
*/
- protected <T> int[] write(final T object)
- throws IOException
+ protected long calculateByteOffsetForBlockAsLong(final int block)
{
- // serialize the object
- final byte[] data = elementSerializer.serialize(object);
-
- log.debug("write, total pre-chunking data.length = {0}", data.length);
-
- this.putBytes.addAndGet(data.length);
- this.putCount.incrementAndGet();
-
- // figure out how many blocks we need.
- final int numBlocksNeeded = calculateTheNumberOfBlocksNeeded(data);
-
- log.debug("numBlocksNeeded = {0}", numBlocksNeeded);
+ return (long) block * blockSizeBytes;
+ }
- // allocate blocks
- final int[] blocks = allocateBlocks(numBlocksNeeded);
+ /**
+ * The number of blocks needed.
+ * <p>
+ * @param data
+ * @return the number of blocks needed to store the byte array
+ */
+ protected int calculateTheNumberOfBlocksNeeded(final byte[] data)
+ {
+ final int dataLength = data.length;
- int offset = 0;
- final int maxChunkSize = blockSizeBytes - HEADER_SIZE_BYTES;
- final ByteBuffer headerBuffer = ByteBuffer.allocate(HEADER_SIZE_BYTES);
- final ByteBuffer dataBuffer = ByteBuffer.wrap(data);
+ final int oneBlock = blockSizeBytes - HEADER_SIZE_BYTES;
- for (int i = 0; i < numBlocksNeeded; i++)
+ // takes care of 0 = HEADER_SIZE_BYTES + blockSizeBytes
+ if (dataLength <= oneBlock)
{
- headerBuffer.clear();
- final int length = Math.min(maxChunkSize, data.length - offset);
- headerBuffer.putInt(length);
- headerBuffer.flip();
+ return 1;
+ }
- dataBuffer.position(offset).limit(offset + length);
- final ByteBuffer slice = dataBuffer.slice();
+ int dividend = dataLength / oneBlock;
- final long position = calculateByteOffsetForBlockAsLong(blocks[i]);
- // write the header
- int written = fc.write(headerBuffer, position);
- assert written == HEADER_SIZE_BYTES;
+ if (dataLength % oneBlock != 0)
+ {
+ dividend++;
+ }
+ return dividend;
+ }
- //write the data
- written = fc.write(slice, position + HEADER_SIZE_BYTES);
- assert written == length;
+ /**
+ * Closes the file.
+ * <p>
+ * @throws IOException
+ */
+ @Override
+ public void close()
+ throws IOException
+ {
+ this.numberOfBlocks.set(0);
+ this.emptyBlocks.clear();
+ fc.close();
+ }
- offset += length;
+ /**
+ * Add these blocks to the emptyBlock list.
+ * <p>
+ * @param blocksToFree
+ */
+ protected void freeBlocks(final int[] blocksToFree)
+ {
+ if (blocksToFree != null)
+ {
+ for (short i = 0; i < blocksToFree.length; i++)
+ {
+ emptyBlocks.offer(Integer.valueOf(blocksToFree[i]));
+ }
}
+ }
- //fc.force(false);
+ /**
+ * @return Returns the average size of the an element inserted.
+ */
+ protected long getAveragePutSizeBytes()
+ {
+ final long count = this.putCount.get();
- return blocks;
+ if (count == 0)
+ {
+ return 0;
+ }
+ return this.putBytes.get() / count;
}
/**
@@ -256,6 +271,52 @@ public class BlockDisk implements AutoCloseable
return chunks;
}
+ /**
+ * @return Returns the blockSizeBytes.
+ */
+ protected int getBlockSizeBytes()
+ {
+ return blockSizeBytes;
+ }
+
+ /**
+ * @return Returns the number of empty blocks.
+ */
+ protected int getEmptyBlocks()
+ {
+ return this.emptyBlocks.size();
+ }
+
+ /**
+ * This is used for debugging.
+ * <p>
+ * @return the file path.
+ */
+ protected String getFilePath()
+ {
+ return filepath;
+ }
+
+ /**
+ * @return Returns the numberOfBlocks.
+ */
+ protected int getNumberOfBlocks()
+ {
+ return numberOfBlocks.get();
+ }
+
+ /**
+ * Returns the file length.
+ * <p>
+ * @return the size of the file.
+ * @throws IOException
+ */
+ protected long length()
+ throws IOException
+ {
+ return fc.size();
+ }
+
/**
* Reads an object that is located in the specified blocks.
* <p>
@@ -342,87 +403,6 @@ public class BlockDisk implements AutoCloseable
return data;
}
- /**
- * Add these blocks to the emptyBlock list.
- * <p>
- * @param blocksToFree
- */
- protected void freeBlocks(final int[] blocksToFree)
- {
- if (blocksToFree != null)
- {
- for (short i = 0; i < blocksToFree.length; i++)
- {
- emptyBlocks.offer(Integer.valueOf(blocksToFree[i]));
- }
- }
- }
-
- /**
- * Calculates the file offset for a particular block.
- * <p>
- * @param block number
- * @return the byte offset for this block in the file as a long
- * @since 2.0
- */
- protected long calculateByteOffsetForBlockAsLong(final int block)
- {
- return (long) block * blockSizeBytes;
- }
-
- /**
- * The number of blocks needed.
- * <p>
- * @param data
- * @return the number of blocks needed to store the byte array
- */
- protected int calculateTheNumberOfBlocksNeeded(final byte[] data)
- {
- final int dataLength = data.length;
-
- final int oneBlock = blockSizeBytes - HEADER_SIZE_BYTES;
-
- // takes care of 0 = HEADER_SIZE_BYTES + blockSizeBytes
- if (dataLength <= oneBlock)
- {
- return 1;
- }
-
- int dividend = dataLength / oneBlock;
-
- if (dataLength % oneBlock != 0)
- {
- dividend++;
- }
- return dividend;
- }
-
- /**
- * Returns the file length.
- * <p>
- * @return the size of the file.
- * @throws IOException
- */
- protected long length()
- throws IOException
- {
- return fc.size();
- }
-
- /**
- * Closes the file.
- * <p>
- * @throws IOException
- */
- @Override
- public void close()
- throws IOException
- {
- this.numberOfBlocks.set(0);
- this.emptyBlocks.clear();
- fc.close();
- }
-
/**
* Resets the file.
* <p>
@@ -437,44 +417,6 @@ public class BlockDisk implements AutoCloseable
fc.force(true);
}
- /**
- * @return Returns the numberOfBlocks.
- */
- protected int getNumberOfBlocks()
- {
- return numberOfBlocks.get();
- }
-
- /**
- * @return Returns the blockSizeBytes.
- */
- protected int getBlockSizeBytes()
- {
- return blockSizeBytes;
- }
-
- /**
- * @return Returns the average size of the an element inserted.
- */
- protected long getAveragePutSizeBytes()
- {
- final long count = this.putCount.get();
-
- if (count == 0)
- {
- return 0;
- }
- return this.putBytes.get() / count;
- }
-
- /**
- * @return Returns the number of empty blocks.
- */
- protected int getEmptyBlocks()
- {
- return this.emptyBlocks.size();
- }
-
/**
* For debugging only.
* <p>
@@ -504,12 +446,70 @@ public class BlockDisk implements AutoCloseable
}
/**
- * This is used for debugging.
+ * This writes an object to disk and returns the blocks it was stored in.
* <p>
- * @return the file path.
+ * The program flow is as follows:
+ * <ol>
+ * <li>Serialize the object.</li>
+ * <li>Determine the number of blocks needed.</li>
+ * <li>Look for free blocks in the emptyBlock list.</li>
+ * <li>If there were not enough in the empty list. Take the nextBlock and increment it.</li>
+ * <li>If the data will not fit in one block, create sub arrays.</li>
+ * <li>Write the subarrays to disk.</li>
+ * <li>If the process fails we should decrement the block count if we took from it.</li>
+ * </ol>
+ * @param object
+ * @return the blocks we used.
+ * @throws IOException
*/
- protected String getFilePath()
+ protected <T> int[] write(final T object)
+ throws IOException
{
- return filepath;
+ // serialize the object
+ final byte[] data = elementSerializer.serialize(object);
+
+ log.debug("write, total pre-chunking data.length = {0}", data.length);
+
+ this.putBytes.addAndGet(data.length);
+ this.putCount.incrementAndGet();
+
+ // figure out how many blocks we need.
+ final int numBlocksNeeded = calculateTheNumberOfBlocksNeeded(data);
+
+ log.debug("numBlocksNeeded = {0}", numBlocksNeeded);
+
+ // allocate blocks
+ final int[] blocks = allocateBlocks(numBlocksNeeded);
+
+ int offset = 0;
+ final int maxChunkSize = blockSizeBytes - HEADER_SIZE_BYTES;
+ final ByteBuffer headerBuffer = ByteBuffer.allocate(HEADER_SIZE_BYTES);
+ final ByteBuffer dataBuffer = ByteBuffer.wrap(data);
+
+ for (int i = 0; i < numBlocksNeeded; i++)
+ {
+ headerBuffer.clear();
+ final int length = Math.min(maxChunkSize, data.length - offset);
+ headerBuffer.putInt(length);
+ headerBuffer.flip();
+
+ dataBuffer.position(offset).limit(offset + length);
+ final ByteBuffer slice = dataBuffer.slice();
+
+ final long position = calculateByteOffsetForBlockAsLong(blocks[i]);
+ // write the header
+ int written = fc.write(headerBuffer, position);
+ assert written == HEADER_SIZE_BYTES;
+
+ //write the data
+ written = fc.write(slice, position + HEADER_SIZE_BYTES);
+ assert written == length;
+
+ offset += length;
+ }
+
+ //fc.force(false);
+
+ return blocks;
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCache.java
index b7f5a7ba..91891125 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCache.java
@@ -152,68 +152,77 @@ public class BlockDiskCache<K, V>
}
/**
- * @see org.apache.commons.jcs3.engine.behavior.IRequireScheduler#setScheduledExecutorService(java.util.concurrent.ScheduledExecutorService)
+ * Internal method that handles the disposal.
*/
- @Override
- public void setScheduledExecutorService(final ScheduledExecutorService scheduledExecutor)
+ protected void disposeInternal()
{
- // add this region to the persistence thread.
- // TODO we might need to stagger this a bit.
- if ( this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds() > 0 )
+ if ( !isAlive() )
{
- future = scheduledExecutor.scheduleAtFixedRate(keyStore::saveKeys,
- this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds(),
- this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds(),
- TimeUnit.SECONDS);
+ log.error("{0}: Not alive and dispose was called, file name: {1}", logCacheName, fileName);
+ return;
+ }
+ storageLock.writeLock().lock();
+ try
+ {
+ // Prevents any interaction with the cache while we're shutting down.
+ setAlive(false);
+ this.keyStore.saveKeys();
+
+ if (future != null)
+ {
+ future.cancel(true);
+ }
+
+ try
+ {
+ log.debug("{0}: Closing files, base file name: {1}", logCacheName, fileName );
+ dataFile.close();
+ // dataFile = null;
+ }
+ catch ( final IOException e )
+ {
+ log.error("{0}: Failure closing files in dispose, file name: {1}",
+ logCacheName, fileName, e );
+ }
}
+ finally
+ {
+ storageLock.writeLock().unlock();
+ }
+
+ log.info("{0}: Shutdown complete.", logCacheName);
}
/**
- * We need to verify that the file on disk uses the same block size and that the file is the
- * proper size.
+ * Add these blocks to the emptyBlock list.
* <p>
- * @return true if it looks ok
+ * @param blocksToFree
*/
- protected boolean verifyDisk()
+ protected void freeBlocks( final int[] blocksToFree )
{
- boolean alright = false;
- // simply try to read a few. If it works, then the file is probably ok.
- // TODO add more.
-
- storageLock.readLock().lock();
+ this.dataFile.freeBlocks( blocksToFree );
+ }
- try
- {
- this.keyStore.entrySet().stream()
- .limit(100)
- .forEach(entry -> {
- try
- {
- final Object data = this.dataFile.read(entry.getValue());
- if ( data == null )
- {
- throw new IOException("Data is null");
- }
- }
- catch (final IOException | ClassNotFoundException e)
- {
- throw new IllegalStateException(logCacheName
- + " Couldn't find data for key [" + entry.getKey() + "]", e);
- }
- });
- alright = true;
- }
- catch ( final Exception e )
- {
- log.warn("{0}: Problem verifying disk.", logCacheName, e);
- alright = false;
- }
- finally
- {
- storageLock.readLock().unlock();
- }
+ /**
+ * Returns the attributes.
+ * <p>
+ * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getAuxiliaryCacheAttributes()
+ */
+ @Override
+ public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+ {
+ return this.blockDiskCacheAttributes;
+ }
- return alright;
+ /**
+ * This is used by the event logging.
+ * <p>
+ * @return the location of the disk, either path or ip.
+ */
+ @Override
+ protected String getDiskLocation()
+ {
+ return dataFile.getFilePath();
}
/**
@@ -241,48 +250,154 @@ public class BlockDiskCache<K, V>
}
/**
- * Gets matching items from the cache.
+ * Returns the number of keys.
* <p>
- * @param pattern
- * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
- * data in cache matching keys
+ * (non-Javadoc)
+ * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#getSize()
*/
@Override
- public Map<K, ICacheElement<K, V>> processGetMatching( final String pattern )
+ public int getSize()
{
- Set<K> keyArray = null;
- storageLock.readLock().lock();
- try
- {
- keyArray = new HashSet<>(keyStore.keySet());
- }
- finally
+ return this.keyStore.size();
+ }
+
+ /**
+ * Returns info about the disk cache.
+ * <p>
+ * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getStatistics()
+ */
+ @Override
+ public IStats getStatistics()
+ {
+ final IStats stats = new Stats();
+ stats.setTypeName( "Block Disk Cache" );
+
+ final ArrayList<IStatElement<?>> elems = new ArrayList<>();
+
+ elems.add(new StatElement<>( "Is Alive", Boolean.valueOf(isAlive()) ) );
+ elems.add(new StatElement<>( "Key Map Size", Integer.valueOf(this.keyStore.size()) ) );
+
+ if (this.dataFile != null)
{
- storageLock.readLock().unlock();
+ try
+ {
+ elems.add(new StatElement<>( "Data File Length", Long.valueOf(this.dataFile.length()) ) );
+ }
+ catch ( final IOException e )
+ {
+ log.error( e );
+ }
+
+ elems.add(new StatElement<>( "Block Size Bytes",
+ Integer.valueOf(this.dataFile.getBlockSizeBytes()) ) );
+ elems.add(new StatElement<>( "Number Of Blocks",
+ Integer.valueOf(this.dataFile.getNumberOfBlocks()) ) );
+ elems.add(new StatElement<>( "Average Put Size Bytes",
+ Long.valueOf(this.dataFile.getAveragePutSizeBytes()) ) );
+ elems.add(new StatElement<>( "Empty Blocks",
+ Integer.valueOf(this.dataFile.getEmptyBlocks()) ) );
}
- final Set<K> matchingKeys = getKeyMatcher().getMatchingKeysFromArray( pattern, keyArray );
+ // get the stats from the super too
+ final IStats sStats = super.getStatistics();
+ elems.addAll(sStats.getStatElements());
- return matchingKeys.stream()
- .collect(Collectors.toMap(
- key -> key,
- this::processGet)).entrySet().stream()
- .filter(entry -> entry.getValue() != null)
- .collect(Collectors.toMap(
- Entry::getKey,
- Entry::getValue));
+ stats.setStatElements( elems );
+
+ return stats;
}
/**
- * Returns the number of keys.
+ * Remove all elements from the group. This does not use the iterator to remove. It builds a
+ * list of group elements and then removes them one by one.
* <p>
- * (non-Javadoc)
- * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#getSize()
+ * This operates under a lock obtained in doRemove().
+ * <p>
+ *
+ * @param key
+ * @return true if an element was removed
+ */
+ private boolean performGroupRemoval(final GroupId key)
+ {
+ // remove all keys of the same name group.
+ final List<K> itemsToRemove = keyStore.keySet()
+ .stream()
+ .filter(k -> k instanceof GroupAttrName && ((GroupAttrName<?>) k).groupId.equals(key))
+ .collect(Collectors.toList());
+
+ // remove matches.
+ // Don't add to recycle bin here
+ // https://issues.apache.org/jira/browse/JCS-67
+ itemsToRemove.forEach(this::performSingleKeyRemoval);
+ // TODO this needs to update the remove count separately
+
+ return !itemsToRemove.isEmpty();
+ }
+
+ /**
+ * Iterates over the keyset. Builds a list of matches. Removes all the keys in the list. Does
+ * not remove via the iterator, since the map impl may not support it.
+ * <p>
+ * This operates under a lock obtained in doRemove().
+ * <p>
+ *
+ * @param key
+ * @return true if there was a match
+ */
+ private boolean performPartialKeyRemoval(final String key)
+ {
+ // remove all keys of the same name hierarchy.
+ final List<K> itemsToRemove = keyStore.keySet()
+ .stream()
+ .filter(k -> k instanceof String && k.toString().startsWith(key))
+ .collect(Collectors.toList());
+
+ // remove matches.
+ // Don't add to recycle bin here
+ // https://issues.apache.org/jira/browse/JCS-67
+ itemsToRemove.forEach(this::performSingleKeyRemoval);
+ // TODO this needs to update the remove count separately
+
+ return !itemsToRemove.isEmpty();
+ }
+
+ private boolean performSingleKeyRemoval(final K key) {
+ final boolean removed;
+ // remove single item.
+ final int[] ded = this.keyStore.remove( key );
+ removed = ded != null;
+ if ( removed )
+ {
+ this.dataFile.freeBlocks( ded );
+ }
+
+ log.debug("{0}: Disk removal: Removed from key hash, key [{1}] removed = {2}",
+ logCacheName, key, removed);
+ return removed;
+ }
+
+
+ /**
+ * Dispose of the disk cache in a background thread. Joins against this thread to put a cap on
+ * the disposal time.
+ * <p>
+ * TODO make dispose window configurable.
*/
@Override
- public int getSize()
+ public void processDispose()
{
- return this.keyStore.size();
+ final Thread t = new Thread(this::disposeInternal, "BlockDiskCache-DisposalThread" );
+ t.start();
+ // wait up to 60 seconds for dispose and then quit if not done.
+ try
+ {
+ t.join( 60 * 1000 );
+ }
+ catch ( final InterruptedException ex )
+ {
+ log.error("{0}: Interrupted while waiting for disposal thread to finish.",
+ logCacheName, ex );
+ }
}
/**
@@ -337,59 +452,36 @@ public class BlockDiskCache<K, V>
}
/**
- * Writes an element to disk. The program flow is as follows:
- * <ol>
- * <li>Acquire write lock.</li> <li>See id an item exists for this key.</li> <li>If an item
- * already exists, add its blocks to the remove list.</li> <li>Have the Block disk write the
- * item.</li> <li>Create a descriptor and add it to the key map.</li> <li>Release the write
- * lock.</li>
- * </ol>
- * @param element
- * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#update(ICacheElement)
+ * Gets matching items from the cache.
+ * <p>
+ * @param pattern
+ * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
+ * data in cache matching keys
*/
@Override
- protected void processUpdate( final ICacheElement<K, V> element )
+ public Map<K, ICacheElement<K, V>> processGetMatching( final String pattern )
{
- if ( !isAlive() )
- {
- log.debug("{0}: No longer alive; aborting put of key = {1}",
- () -> logCacheName, element::getKey);
- return;
- }
-
- int[] old = null;
-
- // make sure this only locks for one particular cache region
- storageLock.writeLock().lock();
-
+ Set<K> keyArray = null;
+ storageLock.readLock().lock();
try
{
- old = this.keyStore.get( element.getKey() );
-
- if ( old != null )
- {
- this.dataFile.freeBlocks( old );
- }
-
- final int[] blocks = this.dataFile.write( element );
-
- this.keyStore.put( element.getKey(), blocks );
-
- log.debug("{0}: Put to file [{1}] key [{2}]", () -> logCacheName,
- () -> fileName, element::getKey);
- }
- catch ( final IOException e )
- {
- log.error("{0}: Failure updating element, key: {1} old: {2}",
- logCacheName, element.getKey(), Arrays.toString(old), e);
+ keyArray = new HashSet<>(keyStore.keySet());
}
finally
{
- storageLock.writeLock().unlock();
+ storageLock.readLock().unlock();
}
- log.debug("{0}: Storing element on disk, key: {1}", () -> logCacheName,
- element::getKey);
+ final Set<K> matchingKeys = getKeyMatcher().getMatchingKeysFromArray( pattern, keyArray );
+
+ return matchingKeys.stream()
+ .collect(Collectors.toMap(
+ key -> key,
+ this::processGet)).entrySet().stream()
+ .filter(entry -> entry.getValue() != null)
+ .collect(Collectors.toMap(
+ Entry::getKey,
+ Entry::getValue));
}
/**
@@ -447,76 +539,6 @@ public class BlockDiskCache<K, V>
return removed;
}
- /**
- * Remove all elements from the group. This does not use the iterator to remove. It builds a
- * list of group elements and then removes them one by one.
- * <p>
- * This operates under a lock obtained in doRemove().
- * <p>
- *
- * @param key
- * @return true if an element was removed
- */
- private boolean performGroupRemoval(final GroupId key)
- {
- // remove all keys of the same name group.
- final List<K> itemsToRemove = keyStore.keySet()
- .stream()
- .filter(k -> k instanceof GroupAttrName && ((GroupAttrName<?>) k).groupId.equals(key))
- .collect(Collectors.toList());
-
- // remove matches.
- // Don't add to recycle bin here
- // https://issues.apache.org/jira/browse/JCS-67
- itemsToRemove.forEach(this::performSingleKeyRemoval);
- // TODO this needs to update the remove count separately
-
- return !itemsToRemove.isEmpty();
- }
-
- /**
- * Iterates over the keyset. Builds a list of matches. Removes all the keys in the list. Does
- * not remove via the iterator, since the map impl may not support it.
- * <p>
- * This operates under a lock obtained in doRemove().
- * <p>
- *
- * @param key
- * @return true if there was a match
- */
- private boolean performPartialKeyRemoval(final String key)
- {
- // remove all keys of the same name hierarchy.
- final List<K> itemsToRemove = keyStore.keySet()
- .stream()
- .filter(k -> k instanceof String && k.toString().startsWith(key))
- .collect(Collectors.toList());
-
- // remove matches.
- // Don't add to recycle bin here
- // https://issues.apache.org/jira/browse/JCS-67
- itemsToRemove.forEach(this::performSingleKeyRemoval);
- // TODO this needs to update the remove count separately
-
- return !itemsToRemove.isEmpty();
- }
-
-
- private boolean performSingleKeyRemoval(final K key) {
- final boolean removed;
- // remove single item.
- final int[] ded = this.keyStore.remove( key );
- removed = ded != null;
- if ( removed )
- {
- this.dataFile.freeBlocks( ded );
- }
-
- log.debug("{0}: Disk removal: Removed from key hash, key [{1}] removed = {2}",
- logCacheName, key, removed);
- return removed;
- }
-
/**
* Resets the keyfile, the disk file, and the memory key map.
* <p>
@@ -529,79 +551,59 @@ public class BlockDiskCache<K, V>
}
/**
- * Dispose of the disk cache in a background thread. Joins against this thread to put a cap on
- * the disposal time.
- * <p>
- * TODO make dispose window configurable.
+ * Writes an element to disk. The program flow is as follows:
+ * <ol>
+ * <li>Acquire write lock.</li> <li>See id an item exists for this key.</li> <li>If an item
+ * already exists, add its blocks to the remove list.</li> <li>Have the Block disk write the
+ * item.</li> <li>Create a descriptor and add it to the key map.</li> <li>Release the write
+ * lock.</li>
+ * </ol>
+ * @param element
+ * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#update(ICacheElement)
*/
@Override
- public void processDispose()
- {
- final Thread t = new Thread(this::disposeInternal, "BlockDiskCache-DisposalThread" );
- t.start();
- // wait up to 60 seconds for dispose and then quit if not done.
- try
- {
- t.join( 60 * 1000 );
- }
- catch ( final InterruptedException ex )
- {
- log.error("{0}: Interrupted while waiting for disposal thread to finish.",
- logCacheName, ex );
- }
- }
-
- /**
- * Internal method that handles the disposal.
- */
- protected void disposeInternal()
+ protected void processUpdate( final ICacheElement<K, V> element )
{
if ( !isAlive() )
{
- log.error("{0}: Not alive and dispose was called, file name: {1}", logCacheName, fileName);
+ log.debug("{0}: No longer alive; aborting put of key = {1}",
+ () -> logCacheName, element::getKey);
return;
}
+
+ int[] old = null;
+
+ // make sure this only locks for one particular cache region
storageLock.writeLock().lock();
+
try
{
- // Prevents any interaction with the cache while we're shutting down.
- setAlive(false);
- this.keyStore.saveKeys();
+ old = this.keyStore.get( element.getKey() );
- if (future != null)
+ if ( old != null )
{
- future.cancel(true);
+ this.dataFile.freeBlocks( old );
}
- try
- {
- log.debug("{0}: Closing files, base file name: {1}", logCacheName, fileName );
- dataFile.close();
- // dataFile = null;
- }
- catch ( final IOException e )
- {
- log.error("{0}: Failure closing files in dispose, file name: {1}",
- logCacheName, fileName, e );
- }
+ final int[] blocks = this.dataFile.write( element );
+
+ this.keyStore.put( element.getKey(), blocks );
+
+ log.debug("{0}: Put to file [{1}] key [{2}]", () -> logCacheName,
+ () -> fileName, element::getKey);
+ }
+ catch ( final IOException e )
+ {
+ log.error("{0}: Failure updating element, key: {1} old: {2}",
+ logCacheName, element.getKey(), Arrays.toString(old), e);
}
finally
{
storageLock.writeLock().unlock();
}
- log.info("{0}: Shutdown complete.", logCacheName);
- }
-
- /**
- * Returns the attributes.
- * <p>
- * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getAuxiliaryCacheAttributes()
- */
- @Override
- public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
- {
- return this.blockDiskCacheAttributes;
+ log.debug("{0}: Storing element on disk, key: {1}", () -> logCacheName,
+ element::getKey);
}
/**
@@ -635,69 +637,67 @@ public class BlockDiskCache<K, V>
}
/**
- * Add these blocks to the emptyBlock list.
- * <p>
- * @param blocksToFree
+ * @see org.apache.commons.jcs3.engine.behavior.IRequireScheduler#setScheduledExecutorService(java.util.concurrent.ScheduledExecutorService)
*/
- protected void freeBlocks( final int[] blocksToFree )
+ @Override
+ public void setScheduledExecutorService(final ScheduledExecutorService scheduledExecutor)
{
- this.dataFile.freeBlocks( blocksToFree );
+ // add this region to the persistence thread.
+ // TODO we might need to stagger this a bit.
+ if ( this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds() > 0 )
+ {
+ future = scheduledExecutor.scheduleAtFixedRate(keyStore::saveKeys,
+ this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds(),
+ this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds(),
+ TimeUnit.SECONDS);
+ }
}
/**
- * Returns info about the disk cache.
+ * We need to verify that the file on disk uses the same block size and that the file is the
+ * proper size.
* <p>
- * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getStatistics()
+ * @return true if it looks ok
*/
- @Override
- public IStats getStatistics()
+ protected boolean verifyDisk()
{
- final IStats stats = new Stats();
- stats.setTypeName( "Block Disk Cache" );
-
- final ArrayList<IStatElement<?>> elems = new ArrayList<>();
+ boolean alright = false;
+ // simply try to read a few. If it works, then the file is probably ok.
+ // TODO add more.
- elems.add(new StatElement<>( "Is Alive", Boolean.valueOf(isAlive()) ) );
- elems.add(new StatElement<>( "Key Map Size", Integer.valueOf(this.keyStore.size()) ) );
+ storageLock.readLock().lock();
- if (this.dataFile != null)
+ try
{
- try
- {
- elems.add(new StatElement<>( "Data File Length", Long.valueOf(this.dataFile.length()) ) );
- }
- catch ( final IOException e )
- {
- log.error( e );
- }
-
- elems.add(new StatElement<>( "Block Size Bytes",
- Integer.valueOf(this.dataFile.getBlockSizeBytes()) ) );
- elems.add(new StatElement<>( "Number Of Blocks",
- Integer.valueOf(this.dataFile.getNumberOfBlocks()) ) );
- elems.add(new StatElement<>( "Average Put Size Bytes",
- Long.valueOf(this.dataFile.getAveragePutSizeBytes()) ) );
- elems.add(new StatElement<>( "Empty Blocks",
- Integer.valueOf(this.dataFile.getEmptyBlocks()) ) );
+ this.keyStore.entrySet().stream()
+ .limit(100)
+ .forEach(entry -> {
+ try
+ {
+ final Object data = this.dataFile.read(entry.getValue());
+ if ( data == null )
+ {
+ throw new IOException("Data is null");
+ }
+ }
+ catch (final IOException | ClassNotFoundException e)
+ {
+ throw new IllegalStateException(logCacheName
+ + " Couldn't find data for key [" + entry.getKey() + "]", e);
+ }
+ });
+ alright = true;
+ }
+ catch ( final Exception e )
+ {
+ log.warn("{0}: Problem verifying disk.", logCacheName, e);
+ alright = false;
+ }
+ finally
+ {
+ storageLock.readLock().unlock();
}
- // get the stats from the super too
- final IStats sStats = super.getStatistics();
- elems.addAll(sStats.getStatElements());
-
- stats.setStatElements( elems );
-
- return stats;
- }
-
- /**
- * This is used by the event logging.
- * <p>
- * @return the location of the disk, either path or ip.
- */
- @Override
- protected String getDiskLocation()
- {
- return dataFile.getFilePath();
+ return alright;
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCacheAttributes.java
index f2629ae8..14a35375 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskCacheAttributes.java
@@ -30,31 +30,21 @@ public class BlockDiskCacheAttributes
/** Don't change */
private static final long serialVersionUID = 6568840097657265989L;
- /** The size per block in bytes. */
- private int blockSizeBytes;
-
/** Maximum number of keys to be kept in memory */
private static final int DEFAULT_MAX_KEY_SIZE = 5000;
- /** -1 means no limit. */
- private int maxKeySize = DEFAULT_MAX_KEY_SIZE;
-
/** How often should we persist the keys. */
private static final long DEFAULT_KEY_PERSISTENCE_INTERVAL_SECONDS = 5 * 60;
+ /** The size per block in bytes. */
+ private int blockSizeBytes;
+
+ /** -1 means no limit. */
+ private int maxKeySize = DEFAULT_MAX_KEY_SIZE;
+
/** The keys will be persisted at this interval. -1 mean never. */
private long keyPersistenceIntervalSeconds = DEFAULT_KEY_PERSISTENCE_INTERVAL_SECONDS;
- /**
- * The size of the blocks. All blocks are the same size.
- * <p>
- * @param blockSizeBytes The blockSizeBytes to set.
- */
- public void setBlockSizeBytes( final int blockSizeBytes )
- {
- this.blockSizeBytes = blockSizeBytes;
- }
-
/**
* @return Returns the blockSizeBytes.
*/
@@ -64,11 +54,11 @@ public class BlockDiskCacheAttributes
}
/**
- * @param maxKeySize The maxKeySize to set.
+ * @return Returns the keyPersistenceIntervalSeconds.
*/
- public void setMaxKeySize( final int maxKeySize )
+ public long getKeyPersistenceIntervalSeconds()
{
- this.maxKeySize = maxKeySize;
+ return keyPersistenceIntervalSeconds;
}
/**
@@ -79,6 +69,16 @@ public class BlockDiskCacheAttributes
return maxKeySize;
}
+ /**
+ * The size of the blocks. All blocks are the same size.
+ * <p>
+ * @param blockSizeBytes The blockSizeBytes to set.
+ */
+ public void setBlockSizeBytes( final int blockSizeBytes )
+ {
+ this.blockSizeBytes = blockSizeBytes;
+ }
+
/**
* @param keyPersistenceIntervalSeconds The keyPersistenceIntervalSeconds to set.
*/
@@ -88,11 +88,11 @@ public class BlockDiskCacheAttributes
}
/**
- * @return Returns the keyPersistenceIntervalSeconds.
+ * @param maxKeySize The maxKeySize to set.
*/
- public long getKeyPersistenceIntervalSeconds()
+ public void setMaxKeySize( final int maxKeySize )
{
- return keyPersistenceIntervalSeconds;
+ this.maxKeySize = maxKeySize;
}
/**
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskElementDescriptor.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskElementDescriptor.java
index f086cb5c..8cafe8c0 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskElementDescriptor.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskElementDescriptor.java
@@ -67,11 +67,13 @@ public class BlockDiskElementDescriptor<K>
}
/**
- * @param key The key to set.
+ * This holds the block numbers. An item my be dispersed between multiple blocks.
+ * <p>
+ * @return Returns the blocks.
*/
- public void setKey( final K key )
+ public int[] getBlocks()
{
- this.key = key;
+ return blocks;
}
/**
@@ -82,6 +84,21 @@ public class BlockDiskElementDescriptor<K>
return key;
}
+ /**
+ * Saves on reflection.
+ * <p>
+ * (non-Javadoc)
+ * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+ */
+ @Override
+ @SuppressWarnings("unchecked") // Need cast to K
+ public void readExternal( final ObjectInput input )
+ throws IOException, ClassNotFoundException
+ {
+ this.key = (K) input.readObject();
+ this.blocks = (int[]) input.readObject();
+ }
+
/**
* @param blocks The blocks to set.
*/
@@ -91,13 +108,11 @@ public class BlockDiskElementDescriptor<K>
}
/**
- * This holds the block numbers. An item my be dispersed between multiple blocks.
- * <p>
- * @return Returns the blocks.
+ * @param key The key to set.
*/
- public int[] getBlocks()
+ public void setKey( final K key )
{
- return blocks;
+ this.key = key;
}
/**
@@ -120,21 +135,6 @@ public class BlockDiskElementDescriptor<K>
return buf.toString();
}
- /**
- * Saves on reflection.
- * <p>
- * (non-Javadoc)
- * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
- */
- @Override
- @SuppressWarnings("unchecked") // Need cast to K
- public void readExternal( final ObjectInput input )
- throws IOException, ClassNotFoundException
- {
- this.key = (K) input.readObject();
- this.blocks = (int[]) input.readObject();
- }
-
/**
* Saves on reflection.
* <p>
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskKeyStore.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskKeyStore.java
index cb2c7f23..10692ff7 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskKeyStore.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/block/BlockDiskKeyStore.java
@@ -212,6 +212,9 @@ public class BlockDiskKeyStore<K>
/** The logger */
private static final Log log = LogManager.getLog(BlockDiskKeyStore.class);
+ /** The key file signature for new-style key files */
+ private final static int KEY_FILE_SIGNATURE = 0x6A63734B; // "jcsK"
+
/** Attributes governing the behavior of the block disk cache. */
private final BlockDiskCacheAttributes blockDiskCacheAttributes;
@@ -221,9 +224,6 @@ public class BlockDiskKeyStore<K>
/** The file where we persist the keys */
private final File keyFile;
- /** The key file signature for new-style key files */
- private final static int KEY_FILE_SIGNATURE = 0x6A63734B; // "jcsK"
-
/** The name to prefix log messages with. */
protected final String logCacheName;
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDisk.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDisk.java
index f18790f5..f9cd291f 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDisk.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDisk.java
@@ -35,12 +35,12 @@ public class IndexedDisk implements AutoCloseable
/** The size of the header that indicates the amount of data stored in an occupied block. */
public static final byte HEADER_SIZE_BYTES = 4;
- /** The serializer. */
- private final IElementSerializer elementSerializer;
-
/** The logger */
private static final Log log = LogManager.getLog(IndexedDisk.class);
+ /** The serializer. */
+ private final IElementSerializer elementSerializer;
+
/** The path to the log directory. */
private final String filepath;
@@ -65,6 +65,98 @@ public class IndexedDisk implements AutoCloseable
StandardOpenOption.WRITE);
}
+ /**
+ * Closes the raf.
+ * <p>
+ * @throws IOException
+ */
+ @Override
+ public void close()
+ throws IOException
+ {
+ fc.close();
+ }
+
+ /**
+ * This is used for debugging.
+ * <p>
+ * @return the file path.
+ */
+ protected String getFilePath()
+ {
+ return filepath;
+ }
+
+ /**
+ * Tests if the length is 0.
+ * @return true if the if the length is 0.
+ * @throws IOException If an I/O error occurs.
+ * @since 3.1
+ */
+ protected boolean isEmpty() throws IOException
+ {
+ return length() == 0;
+ }
+
+ /**
+ * Returns the raf length.
+ *
+ * @return the length of the file.
+ * @throws IOException If an I/O error occurs.
+ */
+ protected long length()
+ throws IOException
+ {
+ return fc.size();
+ }
+
+ /**
+ * Moves the data stored from one position to another. The descriptor's position is updated.
+ * <p>
+ * @param ded
+ * @param newPosition
+ * @throws IOException
+ */
+ protected void move(final IndexedDiskElementDescriptor ded, final long newPosition)
+ throws IOException
+ {
+ final ByteBuffer datalength = ByteBuffer.allocate(HEADER_SIZE_BYTES);
+ fc.read(datalength, ded.pos);
+ datalength.flip();
+ final int length = datalength.getInt();
+
+ if (length != ded.len)
+ {
+ throw new IOException("Mismatched memory and disk length (" + length + ") for " + ded);
+ }
+
+ // TODO: more checks?
+
+ long readPos = ded.pos;
+ long writePos = newPosition;
+
+ // header len + data len
+ int remaining = HEADER_SIZE_BYTES + length;
+ final ByteBuffer buffer = ByteBuffer.allocate(16384);
+
+ while (remaining > 0)
+ {
+ // chunk it
+ final int chunkSize = Math.min(remaining, buffer.capacity());
+ buffer.limit(chunkSize);
+ fc.read(buffer, readPos);
+ buffer.flip();
+ fc.write(buffer, writePos);
+ buffer.clear();
+
+ writePos += chunkSize;
+ readPos += chunkSize;
+ remaining -= chunkSize;
+ }
+
+ ded.pos = newPosition;
+ }
+
/**
* This reads an object from the given starting position on the file.
* <p>
@@ -119,50 +211,29 @@ public class IndexedDisk implements AutoCloseable
}
/**
- * Moves the data stored from one position to another. The descriptor's position is updated.
+ * Sets the raf to empty.
* <p>
- * @param ded
- * @param newPosition
* @throws IOException
*/
- protected void move(final IndexedDiskElementDescriptor ded, final long newPosition)
+ protected synchronized void reset()
throws IOException
{
- final ByteBuffer datalength = ByteBuffer.allocate(HEADER_SIZE_BYTES);
- fc.read(datalength, ded.pos);
- datalength.flip();
- final int length = datalength.getInt();
-
- if (length != ded.len)
- {
- throw new IOException("Mismatched memory and disk length (" + length + ") for " + ded);
- }
-
- // TODO: more checks?
-
- long readPos = ded.pos;
- long writePos = newPosition;
-
- // header len + data len
- int remaining = HEADER_SIZE_BYTES + length;
- final ByteBuffer buffer = ByteBuffer.allocate(16384);
-
- while (remaining > 0)
- {
- // chunk it
- final int chunkSize = Math.min(remaining, buffer.capacity());
- buffer.limit(chunkSize);
- fc.read(buffer, readPos);
- buffer.flip();
- fc.write(buffer, writePos);
- buffer.clear();
-
- writePos += chunkSize;
- readPos += chunkSize;
- remaining -= chunkSize;
- }
+ log.debug("Resetting Indexed File [{0}]", filepath);
+ fc.truncate(0);
+ fc.force(true);
+ }
- ded.pos = newPosition;
+ /**
+ * Truncates the file to a given length.
+ * <p>
+ * @param length the new length of the file
+ * @throws IOException
+ */
+ protected void truncate(final long length)
+ throws IOException
+ {
+ log.info("Truncating file [{0}] to {1}", filepath, length);
+ fc.truncate(length);
}
/**
@@ -216,75 +287,4 @@ public class IndexedDisk implements AutoCloseable
final byte[] data = elementSerializer.serialize(obj);
write(new IndexedDiskElementDescriptor(pos, data.length), data);
}
-
- /**
- * Returns the raf length.
- *
- * @return the length of the file.
- * @throws IOException If an I/O error occurs.
- */
- protected long length()
- throws IOException
- {
- return fc.size();
- }
-
- /**
- * Closes the raf.
- * <p>
- * @throws IOException
- */
- @Override
- public void close()
- throws IOException
- {
- fc.close();
- }
-
- /**
- * Sets the raf to empty.
- * <p>
- * @throws IOException
- */
- protected synchronized void reset()
- throws IOException
- {
- log.debug("Resetting Indexed File [{0}]", filepath);
- fc.truncate(0);
- fc.force(true);
- }
-
- /**
- * Truncates the file to a given length.
- * <p>
- * @param length the new length of the file
- * @throws IOException
- */
- protected void truncate(final long length)
- throws IOException
- {
- log.info("Truncating file [{0}] to {1}", filepath, length);
- fc.truncate(length);
- }
-
- /**
- * This is used for debugging.
- * <p>
- * @return the file path.
- */
- protected String getFilePath()
- {
- return filepath;
- }
-
- /**
- * Tests if the length is 0.
- * @return true if the if the length is 0.
- * @throws IOException If an I/O error occurs.
- * @since 3.1
- */
- protected boolean isEmpty() throws IOException
- {
- return length() == 0;
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java
index cf93bdfd..8cfa25b4 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java
@@ -62,6 +62,157 @@ import org.apache.commons.jcs3.utils.timing.ElapsedTimer;
*/
public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
{
+ /**
+ * Class for recycling and lru. This implements the LRU overflow callback, so we can add items
+ * to the recycle bin. This class counts the elements to decide, when to throw away an element
+ */
+
+ public class LRUMapCountLimited extends LRUMap<K, IndexedDiskElementDescriptor>
+ // implements Serializable
+ {
+ public LRUMapCountLimited(final int maxKeySize)
+ {
+ super(maxKeySize);
+ }
+
+ /**
+ * This is called when the may key size is reached. The least recently used item will be
+ * passed here. We will store the position and size of the spot on disk in the recycle bin.
+ * <p>
+ *
+ * @param key
+ * @param value
+ */
+ @Override
+ protected void processRemovedLRU(final K key, final IndexedDiskElementDescriptor value)
+ {
+ addToRecycleBin(value);
+ log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
+ log.debug("{0}: Key store size: [{1}].", logCacheName, this.size());
+
+ doOptimizeRealTime();
+ }
+ }
+
+ /**
+ * Class for recycling and lru. This implements the LRU overflow callback, so we can add items
+ * to the recycle bin. This class counts the size element to decide, when to throw away an element
+ */
+ public class LRUMapSizeLimited extends AbstractLRUMap<K, IndexedDiskElementDescriptor>
+ {
+ /**
+ * <code>tag</code> tells us which map we are working on.
+ */
+ public static final String TAG = "orig";
+
+ // size of the content in kB
+ private final AtomicInteger contentSize;
+ private final int maxSize;
+
+ /**
+ * Default
+ */
+ public LRUMapSizeLimited()
+ {
+ this(-1);
+ }
+
+ /**
+ * @param maxKeySize
+ */
+ public LRUMapSizeLimited(final int maxKeySize)
+ {
+ this.maxSize = maxKeySize;
+ this.contentSize = new AtomicInteger(0);
+ }
+
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ private void addLengthToCacheSize(final IndexedDiskElementDescriptor value)
+ {
+ contentSize.addAndGet((value.len + IndexedDisk.HEADER_SIZE_BYTES) / 1024 + 1);
+ }
+
+ /**
+ * This is called when the may key size is reached. The least recently used item will be
+ * passed here. We will store the position and size of the spot on disk in the recycle bin.
+ * <p>
+ *
+ * @param key
+ * @param value
+ */
+ @Override
+ protected void processRemovedLRU(final K key, final IndexedDiskElementDescriptor value)
+ {
+ if (value != null)
+ {
+ subLengthFromCacheSize(value);
+ }
+
+ addToRecycleBin(value);
+
+ log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
+ log.debug("{0}: Key store size: [{1}].", logCacheName, this.size());
+
+ doOptimizeRealTime();
+ }
+
+ @Override
+ public IndexedDiskElementDescriptor put(final K key, final IndexedDiskElementDescriptor value)
+ {
+ IndexedDiskElementDescriptor oldValue = null;
+
+ try
+ {
+ oldValue = super.put(key, value);
+ }
+ finally
+ {
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ if (value != null)
+ {
+ addLengthToCacheSize(value);
+ }
+ if (oldValue != null)
+ {
+ subLengthFromCacheSize(oldValue);
+ }
+ }
+
+ return oldValue;
+ }
+
+ @Override
+ public IndexedDiskElementDescriptor remove(final Object key)
+ {
+ IndexedDiskElementDescriptor value = null;
+
+ try
+ {
+ value = super.remove(key);
+ return value;
+ }
+ finally
+ {
+ if (value != null)
+ {
+ subLengthFromCacheSize(value);
+ }
+ }
+ }
+
+ @Override
+ protected boolean shouldRemove()
+ {
+ return maxSize > 0 && contentSize.get() > maxSize && !this.isEmpty();
+ }
+
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ private void subLengthFromCacheSize(final IndexedDiskElementDescriptor value)
+ {
+ contentSize.addAndGet((value.len + IndexedDisk.HEADER_SIZE_BYTES) / -1024 - 1);
+ }
+ }
+
/** The logger */
private static final Log log = LogManager.getLog(IndexedDiskCache.class);
@@ -200,143 +351,91 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
}
/**
- * Tries to create the root directory if it does not already exist.
- * <p>
- *
- * @param cattr
- */
- private void initializeFileSystem(final IndexedDiskCacheAttributes cattr)
- {
- this.rafDir = cattr.getDiskPath();
- log.info("{0}: Cache file root directory: {1}", logCacheName, rafDir);
- }
-
- /**
- * Creates the key and data disk caches.
+ * Add descriptor to recycle bin if it is not null. Adds the length of the item to the bytes
+ * free.
* <p>
- * Loads any keys if they are present and ClearDiskOnStartup is false.
+ * This is called in three places: (1) When an item is removed. All item removals funnel down to the removeSingleItem method.
+ * (2) When an item on disk is updated with a value that will not fit in the previous slot. (3) When the max key size is
+ * reached, the freed slot will be added.
* <p>
*
- * @param cattr
- * @throws IOException
+ * @param ded
*/
- private void initializeKeysAndData(final IndexedDiskCacheAttributes cattr) throws IOException
+ protected void addToRecycleBin(final IndexedDiskElementDescriptor ded)
{
- this.dataFile = new IndexedDisk(new File(rafDir, fileName + ".data"), getElementSerializer());
- this.keyFile = new IndexedDisk(new File(rafDir, fileName + ".key"), getElementSerializer());
-
- if (cattr.isClearDiskOnStartup())
- {
- log.info("{0}: ClearDiskOnStartup is set to true. Ignoring any persisted data.",
- logCacheName);
- initializeEmptyStore();
- }
- else if (!keyFile.isEmpty())
- {
- // If the key file has contents, try to initialize the keys
- // from it. In no keys are loaded reset the data file.
- initializeStoreFromPersistedData();
- }
- else
+ // reuse the spot
+ if (ded != null)
{
- // Otherwise start with a new empty map for the keys, and reset
- // the data file if it has contents.
- initializeEmptyStore();
- }
- }
+ storageLock.readLock().lock();
- /**
- * Initializes an empty disk cache.
- * <p>
- *
- * @throws IOException
- */
- private void initializeEmptyStore() throws IOException
- {
- this.keyHash.clear();
+ try
+ {
+ adjustBytesFree(ded, true);
- if (!dataFile.isEmpty())
- {
- dataFile.reset();
+ if (doRecycle)
+ {
+ recycle.add(ded);
+ log.debug("{0}: recycled ded {1}", logCacheName, ded);
+ }
+ }
+ finally
+ {
+ storageLock.readLock().unlock();
+ }
}
}
/**
- * Loads any persisted data and checks for consistency. If there is a consistency issue, the
- * files are cleared.
+ * To subtract you can pass in false for add..
* <p>
*
- * @throws IOException
+ * @param ded
+ * @param add
*/
- private void initializeStoreFromPersistedData() throws IOException
+ private void adjustBytesFree(final IndexedDiskElementDescriptor ded, final boolean add)
{
- loadKeys();
-
- if (keyHash.isEmpty())
- {
- dataFile.reset();
- }
- else
+ if (ded != null)
{
- final boolean isOk = checkKeyDataConsistency(false);
- if (!isOk)
+ final int amount = ded.len + IndexedDisk.HEADER_SIZE_BYTES;
+
+ if (add)
{
- keyHash.clear();
- keyFile.reset();
- dataFile.reset();
- log.warn("{0}: Corruption detected. Resetting data and keys files.", logCacheName);
+ this.bytesFree.addAndGet(amount);
}
else
{
- synchronized (this)
- {
- startupSize = keyHash.size();
- }
+ this.bytesFree.addAndGet(-amount);
}
}
}
/**
- * Loads the keys from the .key file. The keys are stored in a HashMap on disk. This is
- * converted into a LRUMap.
+ * Detects any overlapping elements. This expects a sorted list.
+ * <p>
+ * The total length of an item is IndexedDisk.RECORD_HEADER + ded.len.
+ * <p>
+ *
+ * @param sortedDescriptors
+ * @return false if there are overlaps.
*/
- protected void loadKeys()
+ protected boolean checkForDedOverlaps(final Collection<IndexedDiskElementDescriptor> sortedDescriptors)
{
- log.debug("{0}: Loading keys for {1}", () -> logCacheName, () -> keyFile.toString());
-
- storageLock.writeLock().lock();
-
- try
- {
- // clear a key map to use.
- keyHash.clear();
-
- final HashMap<K, IndexedDiskElementDescriptor> keys = keyFile.readObject(
- new IndexedDiskElementDescriptor(0, (int) keyFile.length() - IndexedDisk.HEADER_SIZE_BYTES));
-
- if (keys != null)
- {
- log.debug("{0}: Found {1} in keys file.", logCacheName, keys.size());
-
- keyHash.putAll(keys);
-
- log.info("{0}: Loaded keys from [{1}], key count: {2}; up to {3} will be available.",
- () -> logCacheName, () -> fileName, keyHash::size, () -> maxKeySize);
- }
-
- if (log.isTraceEnabled())
+ final ElapsedTimer timer = new ElapsedTimer();
+ boolean isOk = true;
+ long expectedNextPos = 0;
+ for (final IndexedDiskElementDescriptor ded : sortedDescriptors) {
+ if (expectedNextPos > ded.pos)
{
- dump(false);
+ log.error("{0}: Corrupt file: overlapping deds {1}", logCacheName, ded);
+ isOk = false;
+ break;
}
+ expectedNextPos = ded.pos + IndexedDisk.HEADER_SIZE_BYTES + ded.len;
}
- catch (final Exception e)
- {
- log.error("{0}: Problem loading keys for file {1}", logCacheName, fileName, e);
- }
- finally
- {
- storageLock.writeLock().unlock();
- }
+ log.debug("{0}: Check for DED overlaps took {1} ms.", () -> logCacheName,
+ timer::getElapsedTime);
+
+ return isOk;
}
/**
@@ -389,710 +488,551 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
}
/**
- * Detects any overlapping elements. This expects a sorted list.
- * <p>
- * The total length of an item is IndexedDisk.RECORD_HEADER + ded.len.
- * <p>
+ * Create the map for keys that contain the index position on disk.
*
- * @param sortedDescriptors
- * @return false if there are overlaps.
+ * @return a new empty Map for keys and IndexedDiskElementDescriptors
*/
- protected boolean checkForDedOverlaps(final Collection<IndexedDiskElementDescriptor> sortedDescriptors)
+ private Map<K, IndexedDiskElementDescriptor> createInitialKeyMap()
{
- final ElapsedTimer timer = new ElapsedTimer();
- boolean isOk = true;
- long expectedNextPos = 0;
- for (final IndexedDiskElementDescriptor ded : sortedDescriptors) {
- if (expectedNextPos > ded.pos)
+ Map<K, IndexedDiskElementDescriptor> keyMap = null;
+ if (maxKeySize >= 0)
+ {
+ if (this.diskLimitType == DiskLimitType.COUNT)
{
- log.error("{0}: Corrupt file: overlapping deds {1}", logCacheName, ded);
- isOk = false;
- break;
+ keyMap = new LRUMapCountLimited(maxKeySize);
}
- expectedNextPos = ded.pos + IndexedDisk.HEADER_SIZE_BYTES + ded.len;
- }
- log.debug("{0}: Check for DED overlaps took {1} ms.", () -> logCacheName,
- timer::getElapsedTime);
-
- return isOk;
- }
-
- /**
- * Saves key file to disk. This converts the LRUMap to a HashMap for deserialization.
- */
- protected void saveKeys()
- {
- try
- {
- log.info("{0}: Saving keys to: {1}, key count: {2}",
- () -> logCacheName, () -> fileName, keyHash::size);
-
- keyFile.reset();
-
- final HashMap<K, IndexedDiskElementDescriptor> keys = new HashMap<>(keyHash);
- if (!keys.isEmpty())
+ else
{
- keyFile.writeObject(keys, 0);
+ keyMap = new LRUMapSizeLimited(maxKeySize);
}
- log.info("{0}: Finished saving keys.", logCacheName);
+ log.info("{0}: Set maxKeySize to: \"{1}\"", logCacheName, maxKeySize);
}
- catch (final IOException e)
+ else
{
- log.error("{0}: Problem storing keys.", logCacheName, e);
+ // If no max size, use a plain map for memory and processing efficiency.
+ keyMap = new HashMap<>();
+ // keyHash = Collections.synchronizedMap( new HashMap() );
+ log.info("{0}: Set maxKeySize to unlimited", logCacheName);
}
+
+ return keyMap;
}
/**
- * Update the disk cache. Called from the Queue. Makes sure the Item has not been retrieved from
- * purgatory while in queue for disk. Remove items from purgatory when they go to disk.
+ * Creates a snapshot of the IndexedDiskElementDescriptors in the keyHash and returns them
+ * sorted by position in the dataFile.
* <p>
*
- * @param ce
- * The ICacheElement<K, V> to put to disk.
+ * @return Collection<IndexedDiskElementDescriptor>
*/
- @Override
- protected void processUpdate(final ICacheElement<K, V> ce)
+ private Collection<IndexedDiskElementDescriptor> createPositionSortedDescriptorList()
{
- if (!isAlive())
- {
- log.error("{0}: No longer alive; aborting put of key = {1}",
- () -> logCacheName, ce::getKey);
- return;
- }
-
- log.debug("{0}: Storing element on disk, key: {1}",
- () -> logCacheName, ce::getKey);
+ final List<IndexedDiskElementDescriptor> defragList = new ArrayList<>(keyHash.values());
+ defragList.sort(Comparator.comparing(ded1 -> ded1.pos));
- // old element with same key
- IndexedDiskElementDescriptor old = null;
+ return defragList;
+ }
+ /**
+ * Defragments the file in place by compacting out the free space (i.e., moving records
+ * forward). If there were no gaps the resulting file would be the same size as the previous
+ * file. This must be supplied an ordered defragList.
+ * <p>
+ *
+ * @param defragList
+ * sorted list of descriptors for optimization
+ * @param startingPos
+ * the start position in the file
+ * @return this is the potential new file end
+ */
+ private long defragFile(final Collection<IndexedDiskElementDescriptor> defragList, final long startingPos)
+ {
+ final ElapsedTimer timer = new ElapsedTimer();
+ long preFileSize = 0;
+ long postFileSize = 0;
+ long expectedNextPos = 0;
try
{
- IndexedDiskElementDescriptor ded = null;
- final byte[] data = getElementSerializer().serialize(ce);
-
- // make sure this only locks for one particular cache region
- storageLock.writeLock().lock();
- try
+ preFileSize = this.dataFile.length();
+ // find the first gap in the disk and start defragging.
+ expectedNextPos = startingPos;
+ for (final IndexedDiskElementDescriptor element : defragList)
{
- old = keyHash.get(ce.getKey());
-
- // Item with the same key already exists in file.
- // Try to reuse the location if possible.
- if (old != null && data.length <= old.len)
- {
- // Reuse the old ded. The defrag relies on ded updates by reference, not
- // replacement.
- ded = old;
- ded.len = data.length;
- }
- else
+ storageLock.writeLock().lock();
+ try
{
- // we need this to compare in the recycle bin
- ded = new IndexedDiskElementDescriptor(dataFile.length(), data.length);
-
- if (doRecycle)
- {
- final IndexedDiskElementDescriptor rep = recycle.ceiling(ded);
- if (rep != null)
- {
- // remove element from recycle bin
- recycle.remove(rep);
- ded = rep;
- ded.len = data.length;
- recycleCnt++;
- this.adjustBytesFree(ded, false);
- log.debug("{0}: using recycled ded {1} rep.len = {2} ded.len = {3}",
- logCacheName, ded.pos, rep.len, ded.len);
- }
- }
-
- // Put it in the map
- keyHash.put(ce.getKey(), ded);
-
- if (queueInput)
- {
- queuedPutList.add(ded);
- log.debug("{0}: added to queued put list. {1}",
- () -> logCacheName, queuedPutList::size);
- }
-
- // add the old slot to the recycle bin
- if (old != null)
+ if (expectedNextPos != element.pos)
{
- addToRecycleBin(old);
+ dataFile.move(element, expectedNextPos);
}
+ expectedNextPos = element.pos + IndexedDisk.HEADER_SIZE_BYTES + element.len;
+ }
+ finally
+ {
+ storageLock.writeLock().unlock();
}
-
- dataFile.write(ded, data);
- }
- finally
- {
- storageLock.writeLock().unlock();
}
- log.debug("{0}: Put to file: {1}, key: {2}, position: {3}, size: {4}",
- logCacheName, fileName, ce.getKey(), ded.pos, ded.len);
+ postFileSize = this.dataFile.length();
+
+ // this is the potential new file end
+ return expectedNextPos;
}
catch (final IOException e)
{
- log.error("{0}: Failure updating element, key: {1} old: {2}",
- logCacheName, ce.getKey(), old, e);
+ log.error("{0}: Error occurred during defragmentation.", logCacheName, e);
+ }
+ finally
+ {
+ log.info("{0}: Defragmentation took {1}. File Size (before={2}) (after={3}) (truncating to {4})",
+ logCacheName, timer.getElapsedTimeString(), preFileSize, postFileSize, expectedNextPos);
}
+
+ return 0;
}
/**
- * Gets the key, then goes to disk to get the object.
- * <p>
- *
- * @param key
- * @return ICacheElement<K, V> or null
- * @see AbstractDiskCache#doGet
+ * Internal method that handles the disposal.
*/
- @Override
- protected ICacheElement<K, V> processGet(final K key)
+ protected void disposeInternal()
{
if (!isAlive())
{
- log.error("{0}: No longer alive so returning null for key = {1}",
- logCacheName, key);
- return null;
- }
+ log.error("{0}: Not alive and dispose was called, file name: {1}",
+ logCacheName, fileName);
+ return;
+ }
- log.debug("{0}: Trying to get from disk: {1}", logCacheName, key);
+ // Prevents any interaction with the cache while we're shutting down.
+ setAlive(false);
- ICacheElement<K, V> object = null;
- try
+ final Thread optimizationThread = currentOptimizationThread;
+ if (isRealTimeOptimizationEnabled && optimizationThread != null)
{
- storageLock.readLock().lock();
+ // Join with the current optimization thread.
+ log.debug("{0}: In dispose, optimization already in progress; waiting for completion.",
+ logCacheName);
+
try
{
- object = readElement(key);
- }
- finally
- {
- storageLock.readLock().unlock();
+ optimizationThread.join();
}
-
- if (object != null)
+ catch (final InterruptedException e)
{
- hitCount.incrementAndGet();
+ log.error("{0}: Unable to join current optimization thread.",
+ logCacheName, e);
}
}
- catch (final IOException ioe)
+ else if (isShutdownOptimizationEnabled && this.getBytesFree() > 0)
{
- log.error("{0}: Failure getting from disk, key = {1}", logCacheName, key, ioe);
- reset();
+ optimizeFile();
}
- return object;
- }
- /**
- * Gets matching items from the cache.
- * <p>
- *
- * @param pattern
- * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
- * data in cache matching keys
- */
- @Override
- public Map<K, ICacheElement<K, V>> processGetMatching(final String pattern)
- {
- final Map<K, ICacheElement<K, V>> elements = new HashMap<>();
- Set<K> keyArray = null;
- storageLock.readLock().lock();
+ saveKeys();
+
try
{
- keyArray = new HashSet<>(keyHash.keySet());
+ log.debug("{0}: Closing files, base file name: {1}", logCacheName,
+ fileName);
+ dataFile.close();
+ dataFile = null;
+ keyFile.close();
+ keyFile = null;
}
- finally
+ catch (final IOException e)
{
- storageLock.readLock().unlock();
+ log.error("{0}: Failure closing files in dispose, file name: {1}",
+ logCacheName, fileName, e);
}
- final Set<K> matchingKeys = getKeyMatcher().getMatchingKeysFromArray(pattern, keyArray);
+ log.info("{0}: Shutdown complete.", logCacheName);
+ }
- for (final K key : matchingKeys)
+ /**
+ * Performs the check for optimization, and if it is required, do it.
+ */
+ protected void doOptimizeRealTime()
+ {
+ if (isRealTimeOptimizationEnabled && !isOptimizing
+ && removeCount++ >= cattr.getOptimizeAtRemoveCount())
{
- final ICacheElement<K, V> element = processGet(key);
- if (element != null)
+ isOptimizing = true;
+
+ log.info("{0}: Optimizing file. removeCount [{1}] OptimizeAtRemoveCount [{2}]",
+ logCacheName, removeCount, cattr.getOptimizeAtRemoveCount());
+
+ if (currentOptimizationThread == null)
{
- elements.put(key, element);
+ storageLock.writeLock().lock();
+
+ try
+ {
+ if (currentOptimizationThread == null)
+ {
+ currentOptimizationThread = new Thread(() -> {
+ optimizeFile();
+ currentOptimizationThread = null;
+ }, "IndexedDiskCache-OptimizationThread");
+ }
+ }
+ finally
+ {
+ storageLock.writeLock().unlock();
+ }
+
+ if (currentOptimizationThread != null)
+ {
+ currentOptimizationThread.start();
+ }
}
}
- return elements;
}
/**
- * Reads the item from disk.
+ * For debugging. This dumps the values by default.
+ */
+ public void dump()
+ {
+ dump(true);
+ }
+
+ /**
+ * For debugging.
* <p>
*
- * @param key
- * @return ICacheElement
- * @throws IOException
+ * @param dumpValues
+ * A boolean indicating if values should be dumped.
*/
- private ICacheElement<K, V> readElement(final K key) throws IOException
+ public void dump(final boolean dumpValues)
{
- final IndexedDiskElementDescriptor ded = keyHash.get(key);
-
- if (ded != null)
+ if (log.isTraceEnabled())
{
- log.debug("{0}: Found on disk, key: ", logCacheName, key);
+ log.trace("{0}: [dump] Number of keys: {1}", logCacheName, keyHash.size());
- try
- {
- return dataFile.readObject(ded);
- // TODO consider checking key equality and throwing if there is a failure
- }
- catch (final IOException e)
- {
- log.error("{0}: IO Exception, Problem reading object from file", logCacheName, e);
- throw e;
- }
- catch (final Exception e)
+ for (final Map.Entry<K, IndexedDiskElementDescriptor> e : keyHash.entrySet())
{
- log.error("{0}: Exception, Problem reading object from file", logCacheName, e);
- throw new IOException(logCacheName + "Problem reading object from disk.", e);
+ final K key = e.getKey();
+ final IndexedDiskElementDescriptor ded = e.getValue();
+
+ log.trace("{0}: [dump] Disk element, key: {1}, pos: {2}, len: {3}" +
+ (dumpValues ? ", val: " + get(key) : ""),
+ logCacheName, key, ded.pos, ded.len);
}
}
+ }
- return null;
+ /**
+ * @return Returns the AuxiliaryCacheAttributes.
+ */
+ @Override
+ public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+ {
+ return this.cattr;
}
/**
- * Return the keys in this cache.
+ * Returns the number of bytes that are free. When an item is removed, its length is recorded.
+ * When a spot is used form the recycle bin, the length of the item stored is recorded.
* <p>
*
- * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#getKeySet()
+ * @return The number bytes free on the disk file.
*/
- @Override
- public Set<K> getKeySet() throws IOException
+ protected long getBytesFree()
{
- final HashSet<K> keys = new HashSet<>();
+ return this.bytesFree.get();
+ }
+
+ /**
+ * This is for debugging and testing.
+ * <p>
+ *
+ * @return the length of the data file.
+ * @throws IOException
+ */
+ protected long getDataFileSize() throws IOException
+ {
+ long size = 0;
storageLock.readLock().lock();
try
{
- keys.addAll(this.keyHash.keySet());
+ if (dataFile != null)
+ {
+ size = dataFile.length();
+ }
}
finally
{
storageLock.readLock().unlock();
}
- return keys;
+ return size;
}
/**
- * Returns true if the removal was successful; or false if there is nothing to remove. Current
- * implementation always result in a disk orphan.
+ * This is used by the event logging.
* <p>
*
- * @return true if at least one item was removed.
- * @param key
+ * @return the location of the disk, either path or ip.
*/
@Override
- protected boolean processRemove(final K key)
+ protected String getDiskLocation()
{
- if (!isAlive())
- {
- log.error("{0}: No longer alive so returning false for key = {1}", logCacheName, key);
- return false;
- }
+ return dataFile.getFilePath();
+ }
- if (key == null)
- {
- return false;
- }
+ /**
+ * Return the keys in this cache.
+ * <p>
+ *
+ * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#getKeySet()
+ */
+ @Override
+ public Set<K> getKeySet() throws IOException
+ {
+ final HashSet<K> keys = new HashSet<>();
+
+ storageLock.readLock().lock();
- boolean removed = false;
try
{
- storageLock.writeLock().lock();
-
- if (key instanceof String && key.toString().endsWith(NAME_COMPONENT_DELIMITER))
- {
- removed = performPartialKeyRemoval((String) key);
- }
- else if (key instanceof GroupAttrName && ((GroupAttrName<?>) key).attrName == null)
- {
- removed = performGroupRemoval(((GroupAttrName<?>) key).groupId);
- }
- else
- {
- removed = performSingleKeyRemoval(key);
- }
+ keys.addAll(this.keyHash.keySet());
}
finally
{
- storageLock.writeLock().unlock();
- }
-
- // this increments the remove count.
- // there is no reason to call this if an item was not removed.
- if (removed)
- {
- doOptimizeRealTime();
+ storageLock.readLock().unlock();
}
- return removed;
+ return keys;
}
/**
- * Iterates over the keyset. Builds a list of matches. Removes all the keys in the list. Does
- * not remove via the iterator, since the map impl may not support it.
- * <p>
- * This operates under a lock obtained in doRemove().
+ * Returns the size of the recycle bin in number of elements.
* <p>
*
- * @param key
- * @return true if there was a match
+ * @return The number of items in the bin.
*/
- private boolean performPartialKeyRemoval(final String key)
+ protected int getRecyleBinSize()
{
- boolean removed = false;
-
- // remove all keys of the same name hierarchy.
- final List<K> itemsToRemove = new LinkedList<>();
-
- for (final K k : keyHash.keySet())
- {
- if (k instanceof String && k.toString().startsWith(key))
- {
- itemsToRemove.add(k);
- }
- }
-
- // remove matches.
- for (final K fullKey : itemsToRemove)
- {
- // Don't add to recycle bin here
- // https://issues.apache.org/jira/browse/JCS-67
- performSingleKeyRemoval(fullKey);
- removed = true;
- // TODO this needs to update the remove count separately
- }
+ return this.recycle.size();
+ }
- return removed;
+ /**
+ * Returns the number of times we have used spots from the recycle bin.
+ * <p>
+ *
+ * @return The number of spots used.
+ */
+ protected int getRecyleCount()
+ {
+ return this.recycleCnt;
}
/**
- * Remove all elements from the group. This does not use the iterator to remove. It builds a
- * list of group elements and then removes them one by one.
+ * Returns the current cache size.
* <p>
- * This operates under a lock obtained in doRemove().
+ *
+ * @return The size value
+ */
+ @Override
+ public int getSize()
+ {
+ return keyHash.size();
+ }
+
+ /**
+ * Returns info about the disk cache.
* <p>
*
- * @param key
- * @return true if an element was removed
+ * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getStatistics()
*/
- private boolean performGroupRemoval(final GroupId key)
+ @Override
+ public synchronized IStats getStatistics()
{
- boolean removed = false;
+ final IStats stats = new Stats();
+ stats.setTypeName("Indexed Disk Cache");
- // remove all keys of the same name group.
- final List<K> itemsToRemove = new LinkedList<>();
+ final ArrayList<IStatElement<?>> elems = new ArrayList<>();
- // remove all keys of the same name hierarchy.
- for (final K k : keyHash.keySet())
+ elems.add(new StatElement<>("Is Alive", Boolean.valueOf(isAlive())));
+ elems.add(new StatElement<>("Key Map Size", Integer.valueOf(this.keyHash != null ? this.keyHash.size() : -1)));
+ try
{
- if (k instanceof GroupAttrName && ((GroupAttrName<?>) k).groupId.equals(key))
- {
- itemsToRemove.add(k);
- }
+ elems.add(
+ new StatElement<>("Data File Length", Long.valueOf(this.dataFile != null ? this.dataFile.length() : -1L)));
}
-
- // remove matches.
- for (final K fullKey : itemsToRemove)
+ catch (final IOException e)
{
- // Don't add to recycle bin here
- // https://issues.apache.org/jira/browse/JCS-67
- performSingleKeyRemoval(fullKey);
- removed = true;
- // TODO this needs to update the remove count separately
+ log.error(e);
}
+ elems.add(new StatElement<>("Max Key Size", this.maxKeySize));
+ elems.add(new StatElement<>("Hit Count", this.hitCount));
+ elems.add(new StatElement<>("Bytes Free", this.bytesFree));
+ elems.add(new StatElement<>("Optimize Operation Count", Integer.valueOf(this.removeCount)));
+ elems.add(new StatElement<>("Times Optimized", Integer.valueOf(this.timesOptimized)));
+ elems.add(new StatElement<>("Recycle Count", Integer.valueOf(this.recycleCnt)));
+ elems.add(new StatElement<>("Recycle Bin Size", Integer.valueOf(this.recycle.size())));
+ elems.add(new StatElement<>("Startup Size", Integer.valueOf(this.startupSize)));
- return removed;
+ // get the stats from the super too
+ final IStats sStats = super.getStatistics();
+ elems.addAll(sStats.getStatElements());
+
+ stats.setStatElements(elems);
+
+ return stats;
}
/**
- * Removes an individual key from the cache.
- * <p>
- * This operates under a lock obtained in doRemove().
+ * This is exposed for testing.
* <p>
*
- * @param key
- * @return true if an item was removed.
+ * @return Returns the timesOptimized.
*/
- private boolean performSingleKeyRemoval(final K key)
+ protected int getTimesOptimized()
{
- final boolean removed;
- // remove single item.
- final IndexedDiskElementDescriptor ded = keyHash.remove(key);
- removed = ded != null;
- addToRecycleBin(ded);
-
- log.debug("{0}: Disk removal: Removed from key hash, key [{1}] removed = {2}",
- logCacheName, key, removed);
- return removed;
+ return timesOptimized;
}
/**
- * Remove all the items from the disk cache by resetting everything.
+ * Initializes an empty disk cache.
+ * <p>
+ *
+ * @throws IOException
*/
- @Override
- public void processRemoveAll()
+ private void initializeEmptyStore() throws IOException
{
- final ICacheEvent<String> cacheEvent =
- createICacheEvent(getCacheName(), "all", ICacheEventLogger.REMOVEALL_EVENT);
- try
- {
- reset();
- }
- finally
+ this.keyHash.clear();
+
+ if (!dataFile.isEmpty())
{
- logICacheEvent(cacheEvent);
+ dataFile.reset();
}
}
/**
- * Reset effectively clears the disk cache, creating new files, recycle bins, and keymaps.
+ * Tries to create the root directory if it does not already exist.
* <p>
- * It can be used to handle errors by last resort, force content update, or removeall.
+ *
+ * @param cattr
*/
- private void reset()
+ private void initializeFileSystem(final IndexedDiskCacheAttributes cattr)
{
- log.info("{0}: Resetting cache", logCacheName);
-
- try
- {
- storageLock.writeLock().lock();
-
- if (dataFile != null)
- {
- dataFile.close();
- }
-
- final File dataFileTemp = new File(rafDir, fileName + ".data");
- Files.delete(dataFileTemp.toPath());
-
- if (keyFile != null)
- {
- keyFile.close();
- }
- final File keyFileTemp = new File(rafDir, fileName + ".key");
- Files.delete(keyFileTemp.toPath());
+ this.rafDir = cattr.getDiskPath();
+ log.info("{0}: Cache file root directory: {1}", logCacheName, rafDir);
+ }
- dataFile = new IndexedDisk(dataFileTemp, getElementSerializer());
- keyFile = new IndexedDisk(keyFileTemp, getElementSerializer());
+ /**
+ * Creates the key and data disk caches.
+ * <p>
+ * Loads any keys if they are present and ClearDiskOnStartup is false.
+ * <p>
+ *
+ * @param cattr
+ * @throws IOException
+ */
+ private void initializeKeysAndData(final IndexedDiskCacheAttributes cattr) throws IOException
+ {
+ this.dataFile = new IndexedDisk(new File(rafDir, fileName + ".data"), getElementSerializer());
+ this.keyFile = new IndexedDisk(new File(rafDir, fileName + ".key"), getElementSerializer());
- this.recycle.clear();
- this.keyHash.clear();
+ if (cattr.isClearDiskOnStartup())
+ {
+ log.info("{0}: ClearDiskOnStartup is set to true. Ignoring any persisted data.",
+ logCacheName);
+ initializeEmptyStore();
}
- catch (final IOException e)
+ else if (!keyFile.isEmpty())
{
- log.error("{0}: Failure resetting state", logCacheName, e);
+ // If the key file has contents, try to initialize the keys
+ // from it. In no keys are loaded reset the data file.
+ initializeStoreFromPersistedData();
}
- finally
+ else
{
- storageLock.writeLock().unlock();
+ // Otherwise start with a new empty map for the keys, and reset
+ // the data file if it has contents.
+ initializeEmptyStore();
}
}
/**
- * Create the map for keys that contain the index position on disk.
+ * Loads any persisted data and checks for consistency. If there is a consistency issue, the
+ * files are cleared.
+ * <p>
*
- * @return a new empty Map for keys and IndexedDiskElementDescriptors
+ * @throws IOException
*/
- private Map<K, IndexedDiskElementDescriptor> createInitialKeyMap()
+ private void initializeStoreFromPersistedData() throws IOException
{
- Map<K, IndexedDiskElementDescriptor> keyMap = null;
- if (maxKeySize >= 0)
+ loadKeys();
+
+ if (keyHash.isEmpty())
{
- if (this.diskLimitType == DiskLimitType.COUNT)
+ dataFile.reset();
+ }
+ else
+ {
+ final boolean isOk = checkKeyDataConsistency(false);
+ if (!isOk)
{
- keyMap = new LRUMapCountLimited(maxKeySize);
+ keyHash.clear();
+ keyFile.reset();
+ dataFile.reset();
+ log.warn("{0}: Corruption detected. Resetting data and keys files.", logCacheName);
}
else
{
- keyMap = new LRUMapSizeLimited(maxKeySize);
+ synchronized (this)
+ {
+ startupSize = keyHash.size();
+ }
}
-
- log.info("{0}: Set maxKeySize to: \"{1}\"", logCacheName, maxKeySize);
- }
- else
- {
- // If no max size, use a plain map for memory and processing efficiency.
- keyMap = new HashMap<>();
- // keyHash = Collections.synchronizedMap( new HashMap() );
- log.info("{0}: Set maxKeySize to unlimited", logCacheName);
}
-
- return keyMap;
}
/**
- * Dispose of the disk cache in a background thread. Joins against this thread to put a cap on
- * the disposal time.
- * <p>
- * TODO make dispose window configurable.
+ * Loads the keys from the .key file. The keys are stored in a HashMap on disk. This is
+ * converted into a LRUMap.
*/
- @Override
- public void processDispose()
+ protected void loadKeys()
{
- final ICacheEvent<String> cacheEvent = createICacheEvent(getCacheName(), "none", ICacheEventLogger.DISPOSE_EVENT);
+ log.debug("{0}: Loading keys for {1}", () -> logCacheName, () -> keyFile.toString());
+
+ storageLock.writeLock().lock();
+
try
{
- final Thread t = new Thread(this::disposeInternal, "IndexedDiskCache-DisposalThread");
- t.start();
- // wait up to 60 seconds for dispose and then quit if not done.
- try
- {
- t.join(60 * 1000);
- }
- catch (final InterruptedException ex)
- {
- log.error("{0}: Interrupted while waiting for disposal thread to finish.",
- logCacheName, ex);
- }
- }
- finally
- {
- logICacheEvent(cacheEvent);
- }
- }
+ // clear a key map to use.
+ keyHash.clear();
- /**
- * Internal method that handles the disposal.
- */
- protected void disposeInternal()
- {
- if (!isAlive())
- {
- log.error("{0}: Not alive and dispose was called, file name: {1}",
- logCacheName, fileName);
- return;
- }
+ final HashMap<K, IndexedDiskElementDescriptor> keys = keyFile.readObject(
+ new IndexedDiskElementDescriptor(0, (int) keyFile.length() - IndexedDisk.HEADER_SIZE_BYTES));
- // Prevents any interaction with the cache while we're shutting down.
- setAlive(false);
+ if (keys != null)
+ {
+ log.debug("{0}: Found {1} in keys file.", logCacheName, keys.size());
- final Thread optimizationThread = currentOptimizationThread;
- if (isRealTimeOptimizationEnabled && optimizationThread != null)
- {
- // Join with the current optimization thread.
- log.debug("{0}: In dispose, optimization already in progress; waiting for completion.",
- logCacheName);
+ keyHash.putAll(keys);
- try
- {
- optimizationThread.join();
+ log.info("{0}: Loaded keys from [{1}], key count: {2}; up to {3} will be available.",
+ () -> logCacheName, () -> fileName, keyHash::size, () -> maxKeySize);
}
- catch (final InterruptedException e)
+
+ if (log.isTraceEnabled())
{
- log.error("{0}: Unable to join current optimization thread.",
- logCacheName, e);
+ dump(false);
}
}
- else if (isShutdownOptimizationEnabled && this.getBytesFree() > 0)
- {
- optimizeFile();
- }
-
- saveKeys();
-
- try
- {
- log.debug("{0}: Closing files, base file name: {1}", logCacheName,
- fileName);
- dataFile.close();
- dataFile = null;
- keyFile.close();
- keyFile = null;
- }
- catch (final IOException e)
- {
- log.error("{0}: Failure closing files in dispose, file name: {1}",
- logCacheName, fileName, e);
- }
-
- log.info("{0}: Shutdown complete.", logCacheName);
- }
-
- /**
- * Add descriptor to recycle bin if it is not null. Adds the length of the item to the bytes
- * free.
- * <p>
- * This is called in three places: (1) When an item is removed. All item removals funnel down to the removeSingleItem method.
- * (2) When an item on disk is updated with a value that will not fit in the previous slot. (3) When the max key size is
- * reached, the freed slot will be added.
- * <p>
- *
- * @param ded
- */
- protected void addToRecycleBin(final IndexedDiskElementDescriptor ded)
- {
- // reuse the spot
- if (ded != null)
+ catch (final Exception e)
{
- storageLock.readLock().lock();
-
- try
- {
- adjustBytesFree(ded, true);
-
- if (doRecycle)
- {
- recycle.add(ded);
- log.debug("{0}: recycled ded {1}", logCacheName, ded);
- }
- }
- finally
- {
- storageLock.readLock().unlock();
- }
+ log.error("{0}: Problem loading keys for file {1}", logCacheName, fileName, e);
}
- }
-
- /**
- * Performs the check for optimization, and if it is required, do it.
- */
- protected void doOptimizeRealTime()
- {
- if (isRealTimeOptimizationEnabled && !isOptimizing
- && removeCount++ >= cattr.getOptimizeAtRemoveCount())
+ finally
{
- isOptimizing = true;
-
- log.info("{0}: Optimizing file. removeCount [{1}] OptimizeAtRemoveCount [{2}]",
- logCacheName, removeCount, cattr.getOptimizeAtRemoveCount());
-
- if (currentOptimizationThread == null)
- {
- storageLock.writeLock().lock();
-
- try
- {
- if (currentOptimizationThread == null)
- {
- currentOptimizationThread = new Thread(() -> {
- optimizeFile();
- currentOptimizationThread = null;
- }, "IndexedDiskCache-OptimizationThread");
- }
- }
- finally
- {
- storageLock.writeLock().unlock();
- }
-
- if (currentOptimizationThread != null)
- {
- currentOptimizationThread.start();
- }
- }
+ storageLock.writeLock().unlock();
}
}
@@ -1183,440 +1123,500 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
}
/**
- * Defragments the file in place by compacting out the free space (i.e., moving records
- * forward). If there were no gaps the resulting file would be the same size as the previous
- * file. This must be supplied an ordered defragList.
+ * Remove all elements from the group. This does not use the iterator to remove. It builds a
+ * list of group elements and then removes them one by one.
+ * <p>
+ * This operates under a lock obtained in doRemove().
* <p>
*
- * @param defragList
- * sorted list of descriptors for optimization
- * @param startingPos
- * the start position in the file
- * @return this is the potential new file end
+ * @param key
+ * @return true if an element was removed
*/
- private long defragFile(final Collection<IndexedDiskElementDescriptor> defragList, final long startingPos)
+ private boolean performGroupRemoval(final GroupId key)
{
- final ElapsedTimer timer = new ElapsedTimer();
- long preFileSize = 0;
- long postFileSize = 0;
- long expectedNextPos = 0;
- try
- {
- preFileSize = this.dataFile.length();
- // find the first gap in the disk and start defragging.
- expectedNextPos = startingPos;
- for (final IndexedDiskElementDescriptor element : defragList)
- {
- storageLock.writeLock().lock();
- try
- {
- if (expectedNextPos != element.pos)
- {
- dataFile.move(element, expectedNextPos);
- }
- expectedNextPos = element.pos + IndexedDisk.HEADER_SIZE_BYTES + element.len;
- }
- finally
- {
- storageLock.writeLock().unlock();
- }
- }
+ boolean removed = false;
- postFileSize = this.dataFile.length();
+ // remove all keys of the same name group.
+ final List<K> itemsToRemove = new LinkedList<>();
- // this is the potential new file end
- return expectedNextPos;
- }
- catch (final IOException e)
+ // remove all keys of the same name hierarchy.
+ for (final K k : keyHash.keySet())
{
- log.error("{0}: Error occurred during defragmentation.", logCacheName, e);
+ if (k instanceof GroupAttrName && ((GroupAttrName<?>) k).groupId.equals(key))
+ {
+ itemsToRemove.add(k);
+ }
}
- finally
+
+ // remove matches.
+ for (final K fullKey : itemsToRemove)
{
- log.info("{0}: Defragmentation took {1}. File Size (before={2}) (after={3}) (truncating to {4})",
- logCacheName, timer.getElapsedTimeString(), preFileSize, postFileSize, expectedNextPos);
+ // Don't add to recycle bin here
+ // https://issues.apache.org/jira/browse/JCS-67
+ performSingleKeyRemoval(fullKey);
+ removed = true;
+ // TODO this needs to update the remove count separately
}
- return 0;
+ return removed;
}
/**
- * Creates a snapshot of the IndexedDiskElementDescriptors in the keyHash and returns them
- * sorted by position in the dataFile.
+ * Iterates over the keyset. Builds a list of matches. Removes all the keys in the list. Does
+ * not remove via the iterator, since the map impl may not support it.
* <p>
- *
- * @return Collection<IndexedDiskElementDescriptor>
- */
- private Collection<IndexedDiskElementDescriptor> createPositionSortedDescriptorList()
- {
- final List<IndexedDiskElementDescriptor> defragList = new ArrayList<>(keyHash.values());
- defragList.sort(Comparator.comparing(ded1 -> ded1.pos));
-
- return defragList;
- }
-
- /**
- * Returns the current cache size.
+ * This operates under a lock obtained in doRemove().
* <p>
*
- * @return The size value
+ * @param key
+ * @return true if there was a match
*/
- @Override
- public int getSize()
+ private boolean performPartialKeyRemoval(final String key)
{
- return keyHash.size();
- }
+ boolean removed = false;
- /**
- * Returns the size of the recycle bin in number of elements.
- * <p>
- *
- * @return The number of items in the bin.
- */
- protected int getRecyleBinSize()
- {
- return this.recycle.size();
- }
+ // remove all keys of the same name hierarchy.
+ final List<K> itemsToRemove = new LinkedList<>();
- /**
- * Returns the number of times we have used spots from the recycle bin.
- * <p>
- *
- * @return The number of spots used.
- */
- protected int getRecyleCount()
- {
- return this.recycleCnt;
+ for (final K k : keyHash.keySet())
+ {
+ if (k instanceof String && k.toString().startsWith(key))
+ {
+ itemsToRemove.add(k);
+ }
+ }
+
+ // remove matches.
+ for (final K fullKey : itemsToRemove)
+ {
+ // Don't add to recycle bin here
+ // https://issues.apache.org/jira/browse/JCS-67
+ performSingleKeyRemoval(fullKey);
+ removed = true;
+ // TODO this needs to update the remove count separately
+ }
+
+ return removed;
}
/**
- * Returns the number of bytes that are free. When an item is removed, its length is recorded.
- * When a spot is used form the recycle bin, the length of the item stored is recorded.
+ * Removes an individual key from the cache.
+ * <p>
+ * This operates under a lock obtained in doRemove().
* <p>
*
- * @return The number bytes free on the disk file.
+ * @param key
+ * @return true if an item was removed.
*/
- protected long getBytesFree()
+ private boolean performSingleKeyRemoval(final K key)
{
- return this.bytesFree.get();
+ final boolean removed;
+ // remove single item.
+ final IndexedDiskElementDescriptor ded = keyHash.remove(key);
+ removed = ded != null;
+ addToRecycleBin(ded);
+
+ log.debug("{0}: Disk removal: Removed from key hash, key [{1}] removed = {2}",
+ logCacheName, key, removed);
+ return removed;
}
/**
- * Resets the number of bytes that are free.
+ * Dispose of the disk cache in a background thread. Joins against this thread to put a cap on
+ * the disposal time.
+ * <p>
+ * TODO make dispose window configurable.
*/
- private void resetBytesFree()
+ @Override
+ public void processDispose()
{
- this.bytesFree.set(0);
+ final ICacheEvent<String> cacheEvent = createICacheEvent(getCacheName(), "none", ICacheEventLogger.DISPOSE_EVENT);
+ try
+ {
+ final Thread t = new Thread(this::disposeInternal, "IndexedDiskCache-DisposalThread");
+ t.start();
+ // wait up to 60 seconds for dispose and then quit if not done.
+ try
+ {
+ t.join(60 * 1000);
+ }
+ catch (final InterruptedException ex)
+ {
+ log.error("{0}: Interrupted while waiting for disposal thread to finish.",
+ logCacheName, ex);
+ }
+ }
+ finally
+ {
+ logICacheEvent(cacheEvent);
+ }
}
/**
- * To subtract you can pass in false for add..
+ * Gets the key, then goes to disk to get the object.
* <p>
*
- * @param ded
- * @param add
+ * @param key
+ * @return ICacheElement<K, V> or null
+ * @see AbstractDiskCache#doGet
*/
- private void adjustBytesFree(final IndexedDiskElementDescriptor ded, final boolean add)
+ @Override
+ protected ICacheElement<K, V> processGet(final K key)
{
- if (ded != null)
+ if (!isAlive())
{
- final int amount = ded.len + IndexedDisk.HEADER_SIZE_BYTES;
+ log.error("{0}: No longer alive so returning null for key = {1}",
+ logCacheName, key);
+ return null;
+ }
- if (add)
+ log.debug("{0}: Trying to get from disk: {1}", logCacheName, key);
+
+ ICacheElement<K, V> object = null;
+ try
+ {
+ storageLock.readLock().lock();
+ try
{
- this.bytesFree.addAndGet(amount);
+ object = readElement(key);
}
- else
+ finally
{
- this.bytesFree.addAndGet(-amount);
+ storageLock.readLock().unlock();
}
+
+ if (object != null)
+ {
+ hitCount.incrementAndGet();
+ }
+ }
+ catch (final IOException ioe)
+ {
+ log.error("{0}: Failure getting from disk, key = {1}", logCacheName, key, ioe);
+ reset();
}
+ return object;
}
/**
- * This is for debugging and testing.
+ * Gets matching items from the cache.
* <p>
*
- * @return the length of the data file.
- * @throws IOException
+ * @param pattern
+ * @return a map of K key to ICacheElement<K, V> element, or an empty map if there is no
+ * data in cache matching keys
*/
- protected long getDataFileSize() throws IOException
+ @Override
+ public Map<K, ICacheElement<K, V>> processGetMatching(final String pattern)
{
- long size = 0;
-
+ final Map<K, ICacheElement<K, V>> elements = new HashMap<>();
+ Set<K> keyArray = null;
storageLock.readLock().lock();
-
try
{
- if (dataFile != null)
- {
- size = dataFile.length();
- }
+ keyArray = new HashSet<>(keyHash.keySet());
}
finally
{
storageLock.readLock().unlock();
}
- return size;
- }
+ final Set<K> matchingKeys = getKeyMatcher().getMatchingKeysFromArray(pattern, keyArray);
- /**
- * For debugging. This dumps the values by default.
- */
- public void dump()
- {
- dump(true);
+ for (final K key : matchingKeys)
+ {
+ final ICacheElement<K, V> element = processGet(key);
+ if (element != null)
+ {
+ elements.put(key, element);
+ }
+ }
+ return elements;
}
/**
- * For debugging.
+ * Returns true if the removal was successful; or false if there is nothing to remove. Current
+ * implementation always result in a disk orphan.
* <p>
*
- * @param dumpValues
- * A boolean indicating if values should be dumped.
+ * @return true if at least one item was removed.
+ * @param key
*/
- public void dump(final boolean dumpValues)
+ @Override
+ protected boolean processRemove(final K key)
{
- if (log.isTraceEnabled())
+ if (!isAlive())
{
- log.trace("{0}: [dump] Number of keys: {1}", logCacheName, keyHash.size());
+ log.error("{0}: No longer alive so returning false for key = {1}", logCacheName, key);
+ return false;
+ }
- for (final Map.Entry<K, IndexedDiskElementDescriptor> e : keyHash.entrySet())
- {
- final K key = e.getKey();
- final IndexedDiskElementDescriptor ded = e.getValue();
+ if (key == null)
+ {
+ return false;
+ }
- log.trace("{0}: [dump] Disk element, key: {1}, pos: {2}, len: {3}" +
- (dumpValues ? ", val: " + get(key) : ""),
- logCacheName, key, ded.pos, ded.len);
+ boolean removed = false;
+ try
+ {
+ storageLock.writeLock().lock();
+
+ if (key instanceof String && key.toString().endsWith(NAME_COMPONENT_DELIMITER))
+ {
+ removed = performPartialKeyRemoval((String) key);
+ }
+ else if (key instanceof GroupAttrName && ((GroupAttrName<?>) key).attrName == null)
+ {
+ removed = performGroupRemoval(((GroupAttrName<?>) key).groupId);
}
+ else
+ {
+ removed = performSingleKeyRemoval(key);
+ }
+ }
+ finally
+ {
+ storageLock.writeLock().unlock();
}
+
+ // this increments the remove count.
+ // there is no reason to call this if an item was not removed.
+ if (removed)
+ {
+ doOptimizeRealTime();
+ }
+
+ return removed;
}
/**
- * @return Returns the AuxiliaryCacheAttributes.
+ * Remove all the items from the disk cache by resetting everything.
*/
@Override
- public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+ public void processRemoveAll()
{
- return this.cattr;
+ final ICacheEvent<String> cacheEvent =
+ createICacheEvent(getCacheName(), "all", ICacheEventLogger.REMOVEALL_EVENT);
+ try
+ {
+ reset();
+ }
+ finally
+ {
+ logICacheEvent(cacheEvent);
+ }
}
/**
- * Returns info about the disk cache.
+ * Update the disk cache. Called from the Queue. Makes sure the Item has not been retrieved from
+ * purgatory while in queue for disk. Remove items from purgatory when they go to disk.
* <p>
*
- * @see org.apache.commons.jcs3.auxiliary.AuxiliaryCache#getStatistics()
+ * @param ce
+ * The ICacheElement<K, V> to put to disk.
*/
@Override
- public synchronized IStats getStatistics()
+ protected void processUpdate(final ICacheElement<K, V> ce)
{
- final IStats stats = new Stats();
- stats.setTypeName("Indexed Disk Cache");
+ if (!isAlive())
+ {
+ log.error("{0}: No longer alive; aborting put of key = {1}",
+ () -> logCacheName, ce::getKey);
+ return;
+ }
- final ArrayList<IStatElement<?>> elems = new ArrayList<>();
+ log.debug("{0}: Storing element on disk, key: {1}",
+ () -> logCacheName, ce::getKey);
+
+ // old element with same key
+ IndexedDiskElementDescriptor old = null;
- elems.add(new StatElement<>("Is Alive", Boolean.valueOf(isAlive())));
- elems.add(new StatElement<>("Key Map Size", Integer.valueOf(this.keyHash != null ? this.keyHash.size() : -1)));
try
{
- elems.add(
- new StatElement<>("Data File Length", Long.valueOf(this.dataFile != null ? this.dataFile.length() : -1L)));
- }
- catch (final IOException e)
- {
- log.error(e);
- }
- elems.add(new StatElement<>("Max Key Size", this.maxKeySize));
- elems.add(new StatElement<>("Hit Count", this.hitCount));
- elems.add(new StatElement<>("Bytes Free", this.bytesFree));
- elems.add(new StatElement<>("Optimize Operation Count", Integer.valueOf(this.removeCount)));
- elems.add(new StatElement<>("Times Optimized", Integer.valueOf(this.timesOptimized)));
- elems.add(new StatElement<>("Recycle Count", Integer.valueOf(this.recycleCnt)));
- elems.add(new StatElement<>("Recycle Bin Size", Integer.valueOf(this.recycle.size())));
- elems.add(new StatElement<>("Startup Size", Integer.valueOf(this.startupSize)));
-
- // get the stats from the super too
- final IStats sStats = super.getStatistics();
- elems.addAll(sStats.getStatElements());
+ IndexedDiskElementDescriptor ded = null;
+ final byte[] data = getElementSerializer().serialize(ce);
- stats.setStatElements(elems);
+ // make sure this only locks for one particular cache region
+ storageLock.writeLock().lock();
+ try
+ {
+ old = keyHash.get(ce.getKey());
- return stats;
- }
+ // Item with the same key already exists in file.
+ // Try to reuse the location if possible.
+ if (old != null && data.length <= old.len)
+ {
+ // Reuse the old ded. The defrag relies on ded updates by reference, not
+ // replacement.
+ ded = old;
+ ded.len = data.length;
+ }
+ else
+ {
+ // we need this to compare in the recycle bin
+ ded = new IndexedDiskElementDescriptor(dataFile.length(), data.length);
- /**
- * This is exposed for testing.
- * <p>
- *
- * @return Returns the timesOptimized.
- */
- protected int getTimesOptimized()
- {
- return timesOptimized;
- }
+ if (doRecycle)
+ {
+ final IndexedDiskElementDescriptor rep = recycle.ceiling(ded);
+ if (rep != null)
+ {
+ // remove element from recycle bin
+ recycle.remove(rep);
+ ded = rep;
+ ded.len = data.length;
+ recycleCnt++;
+ this.adjustBytesFree(ded, false);
+ log.debug("{0}: using recycled ded {1} rep.len = {2} ded.len = {3}",
+ logCacheName, ded.pos, rep.len, ded.len);
+ }
+ }
- /**
- * This is used by the event logging.
- * <p>
- *
- * @return the location of the disk, either path or ip.
- */
- @Override
- protected String getDiskLocation()
- {
- return dataFile.getFilePath();
- }
+ // Put it in the map
+ keyHash.put(ce.getKey(), ded);
- /**
- * Class for recycling and lru. This implements the LRU overflow callback, so we can add items
- * to the recycle bin. This class counts the size element to decide, when to throw away an element
- */
- public class LRUMapSizeLimited extends AbstractLRUMap<K, IndexedDiskElementDescriptor>
- {
- /**
- * <code>tag</code> tells us which map we are working on.
- */
- public static final String TAG = "orig";
+ if (queueInput)
+ {
+ queuedPutList.add(ded);
+ log.debug("{0}: added to queued put list. {1}",
+ () -> logCacheName, queuedPutList::size);
+ }
- // size of the content in kB
- private final AtomicInteger contentSize;
- private final int maxSize;
+ // add the old slot to the recycle bin
+ if (old != null)
+ {
+ addToRecycleBin(old);
+ }
+ }
- /**
- * Default
- */
- public LRUMapSizeLimited()
- {
- this(-1);
- }
+ dataFile.write(ded, data);
+ }
+ finally
+ {
+ storageLock.writeLock().unlock();
+ }
- /**
- * @param maxKeySize
- */
- public LRUMapSizeLimited(final int maxKeySize)
- {
- this.maxSize = maxKeySize;
- this.contentSize = new AtomicInteger(0);
+ log.debug("{0}: Put to file: {1}, key: {2}, position: {3}, size: {4}",
+ logCacheName, fileName, ce.getKey(), ded.pos, ded.len);
}
-
- // keep the content size in kB, so 2^31 kB is reasonable value
- private void subLengthFromCacheSize(final IndexedDiskElementDescriptor value)
+ catch (final IOException e)
{
- contentSize.addAndGet((value.len + IndexedDisk.HEADER_SIZE_BYTES) / -1024 - 1);
+ log.error("{0}: Failure updating element, key: {1} old: {2}",
+ logCacheName, ce.getKey(), old, e);
}
+ }
- // keep the content size in kB, so 2^31 kB is reasonable value
- private void addLengthToCacheSize(final IndexedDiskElementDescriptor value)
- {
- contentSize.addAndGet((value.len + IndexedDisk.HEADER_SIZE_BYTES) / 1024 + 1);
- }
+ /**
+ * Reads the item from disk.
+ * <p>
+ *
+ * @param key
+ * @return ICacheElement
+ * @throws IOException
+ */
+ private ICacheElement<K, V> readElement(final K key) throws IOException
+ {
+ final IndexedDiskElementDescriptor ded = keyHash.get(key);
- @Override
- public IndexedDiskElementDescriptor put(final K key, final IndexedDiskElementDescriptor value)
+ if (ded != null)
{
- IndexedDiskElementDescriptor oldValue = null;
+ log.debug("{0}: Found on disk, key: ", logCacheName, key);
try
{
- oldValue = super.put(key, value);
+ return dataFile.readObject(ded);
+ // TODO consider checking key equality and throwing if there is a failure
}
- finally
+ catch (final IOException e)
{
- // keep the content size in kB, so 2^31 kB is reasonable value
- if (value != null)
- {
- addLengthToCacheSize(value);
- }
- if (oldValue != null)
- {
- subLengthFromCacheSize(oldValue);
- }
+ log.error("{0}: IO Exception, Problem reading object from file", logCacheName, e);
+ throw e;
+ }
+ catch (final Exception e)
+ {
+ log.error("{0}: Exception, Problem reading object from file", logCacheName, e);
+ throw new IOException(logCacheName + "Problem reading object from disk.", e);
}
-
- return oldValue;
}
- @Override
- public IndexedDiskElementDescriptor remove(final Object key)
+ return null;
+ }
+
+ /**
+ * Reset effectively clears the disk cache, creating new files, recycle bins, and keymaps.
+ * <p>
+ * It can be used to handle errors by last resort, force content update, or removeall.
+ */
+ private void reset()
+ {
+ log.info("{0}: Resetting cache", logCacheName);
+
+ try
{
- IndexedDiskElementDescriptor value = null;
+ storageLock.writeLock().lock();
- try
- {
- value = super.remove(key);
- return value;
- }
- finally
+ if (dataFile != null)
{
- if (value != null)
- {
- subLengthFromCacheSize(value);
- }
+ dataFile.close();
}
- }
- /**
- * This is called when the may key size is reached. The least recently used item will be
- * passed here. We will store the position and size of the spot on disk in the recycle bin.
- * <p>
- *
- * @param key
- * @param value
- */
- @Override
- protected void processRemovedLRU(final K key, final IndexedDiskElementDescriptor value)
- {
- if (value != null)
+ final File dataFileTemp = new File(rafDir, fileName + ".data");
+ Files.delete(dataFileTemp.toPath());
+
+ if (keyFile != null)
{
- subLengthFromCacheSize(value);
+ keyFile.close();
}
+ final File keyFileTemp = new File(rafDir, fileName + ".key");
+ Files.delete(keyFileTemp.toPath());
- addToRecycleBin(value);
-
- log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
- log.debug("{0}: Key store size: [{1}].", logCacheName, this.size());
+ dataFile = new IndexedDisk(dataFileTemp, getElementSerializer());
+ keyFile = new IndexedDisk(keyFileTemp, getElementSerializer());
- doOptimizeRealTime();
+ this.recycle.clear();
+ this.keyHash.clear();
}
-
- @Override
- protected boolean shouldRemove()
+ catch (final IOException e)
{
- return maxSize > 0 && contentSize.get() > maxSize && !this.isEmpty();
+ log.error("{0}: Failure resetting state", logCacheName, e);
+ }
+ finally
+ {
+ storageLock.writeLock().unlock();
}
}
/**
- * Class for recycling and lru. This implements the LRU overflow callback, so we can add items
- * to the recycle bin. This class counts the elements to decide, when to throw away an element
+ * Resets the number of bytes that are free.
*/
+ private void resetBytesFree()
+ {
+ this.bytesFree.set(0);
+ }
- public class LRUMapCountLimited extends LRUMap<K, IndexedDiskElementDescriptor>
- // implements Serializable
+ /**
+ * Saves key file to disk. This converts the LRUMap to a HashMap for deserialization.
+ */
+ protected void saveKeys()
{
- public LRUMapCountLimited(final int maxKeySize)
+ try
{
- super(maxKeySize);
- }
+ log.info("{0}: Saving keys to: {1}, key count: {2}",
+ () -> logCacheName, () -> fileName, keyHash::size);
- /**
- * This is called when the may key size is reached. The least recently used item will be
- * passed here. We will store the position and size of the spot on disk in the recycle bin.
- * <p>
- *
- * @param key
- * @param value
- */
- @Override
- protected void processRemovedLRU(final K key, final IndexedDiskElementDescriptor value)
- {
- addToRecycleBin(value);
- log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
- log.debug("{0}: Key store size: [{1}].", logCacheName, this.size());
+ keyFile.reset();
- doOptimizeRealTime();
+ final HashMap<K, IndexedDiskElementDescriptor> keys = new HashMap<>(keyHash);
+ if (!keys.isEmpty())
+ {
+ keyFile.writeObject(keys, 0);
+ }
+
+ log.info("{0}: Finished saving keys.", logCacheName);
+ }
+ catch (final IOException e)
+ {
+ log.error("{0}: Problem storing keys.", logCacheName, e);
}
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java
index a60f0d52..6b7d2fb6 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java
@@ -33,21 +33,21 @@ public class IndexedDiskCacheAttributes
/** default value */
private static final int DEFAULT_maxKeySize = 5000;
+ /** Should we optimize on shutdown. */
+ public static final boolean DEFAULT_OPTIMIZE_ON_SHUTDOWN = true;
+
+ /** Should we clear the disk on startup. */
+ public static final boolean DEFAULT_CLEAR_DISK_ON_STARTUP = false;
+
/** -1 means no limit. */
private int maxKeySize = DEFAULT_maxKeySize;
/** default to -1, i.e., don't optimize until shutdown */
private int optimizeAtRemoveCount = -1;
- /** Should we optimize on shutdown. */
- public static final boolean DEFAULT_OPTIMIZE_ON_SHUTDOWN = true;
-
/** Should we optimize on shutdown. */
private boolean optimizeOnShutdown = DEFAULT_OPTIMIZE_ON_SHUTDOWN;
- /** Should we clear the disk on startup. */
- public static final boolean DEFAULT_CLEAR_DISK_ON_STARTUP = false;
-
/** Should we clear the disk on startup. If true the contents of disk are cleared. */
private boolean clearDiskOnStartup = DEFAULT_CLEAR_DISK_ON_STARTUP;
@@ -68,16 +68,6 @@ public class IndexedDiskCacheAttributes
return this.maxKeySize;
}
- /**
- * Sets the maxKeySize attribute of the DiskCacheAttributes object
- * <p>
- * @param maxKeySize The new maxKeySize value
- */
- public void setMaxKeySize( final int maxKeySize )
- {
- this.maxKeySize = maxKeySize;
- }
-
/**
* Gets the optimizeAtRemoveCount attribute of the DiskCacheAttributes object
* <p>
@@ -89,22 +79,11 @@ public class IndexedDiskCacheAttributes
}
/**
- * Sets the optimizeAtRemoveCount attribute of the DiskCacheAttributes object This number
- * determines how often the disk cache should run real time optimizations.
- * <p>
- * @param cnt The new optimizeAtRemoveCount value
- */
- public void setOptimizeAtRemoveCount( final int cnt )
- {
- this.optimizeAtRemoveCount = cnt;
- }
-
- /**
- * @param optimizeOnShutdown The optimizeOnShutdown to set.
+ * @return the clearDiskOnStartup
*/
- public void setOptimizeOnShutdown( final boolean optimizeOnShutdown )
+ public boolean isClearDiskOnStartup()
{
- this.optimizeOnShutdown = optimizeOnShutdown;
+ return clearDiskOnStartup;
}
/**
@@ -124,11 +103,32 @@ public class IndexedDiskCacheAttributes
}
/**
- * @return the clearDiskOnStartup
+ * Sets the maxKeySize attribute of the DiskCacheAttributes object
+ * <p>
+ * @param maxKeySize The new maxKeySize value
*/
- public boolean isClearDiskOnStartup()
+ public void setMaxKeySize( final int maxKeySize )
{
- return clearDiskOnStartup;
+ this.maxKeySize = maxKeySize;
+ }
+
+ /**
+ * Sets the optimizeAtRemoveCount attribute of the DiskCacheAttributes object This number
+ * determines how often the disk cache should run real time optimizations.
+ * <p>
+ * @param cnt The new optimizeAtRemoveCount value
+ */
+ public void setOptimizeAtRemoveCount( final int cnt )
+ {
+ this.optimizeAtRemoveCount = cnt;
+ }
+
+ /**
+ * @param optimizeOnShutdown The optimizeOnShutdown to set.
+ */
+ public void setOptimizeOnShutdown( final boolean optimizeOnShutdown )
+ {
+ this.optimizeOnShutdown = optimizeOnShutdown;
}
/**
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java
index c2fdd7e2..f3854e49 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java
@@ -50,26 +50,26 @@ public class IndexedDiskElementDescriptor
}
/**
- * @return debug string
+ * Compares based on length, then on pos descending.
+ * <p>
+ * @param o Object
+ * @return int
*/
@Override
- public String toString()
+ public int compareTo( final IndexedDiskElementDescriptor o )
{
- final StringBuilder buf = new StringBuilder();
- buf.append( "[DED: " );
- buf.append( " pos = " + pos );
- buf.append( " len = " + len );
- buf.append( "]" );
- return buf.toString();
- }
+ if ( o == null )
+ {
+ return 1;
+ }
- /**
- * @see Object#hashCode()
- */
- @Override
- public int hashCode()
- {
- return Long.valueOf(this.pos).hashCode() ^ Integer.valueOf(len).hashCode();
+ int lenCompare = Integer.compare(len, o.len);
+ if (lenCompare == 0)
+ {
+ return Long.compare(o.pos, pos);
+ }
+
+ return lenCompare;
}
/**
@@ -92,25 +92,25 @@ public class IndexedDiskElementDescriptor
}
/**
- * Compares based on length, then on pos descending.
- * <p>
- * @param o Object
- * @return int
+ * @see Object#hashCode()
*/
@Override
- public int compareTo( final IndexedDiskElementDescriptor o )
+ public int hashCode()
{
- if ( o == null )
- {
- return 1;
- }
-
- int lenCompare = Integer.compare(len, o.len);
- if (lenCompare == 0)
- {
- return Long.compare(o.pos, pos);
- }
+ return Long.valueOf(this.pos).hashCode() ^ Integer.valueOf(len).hashCode();
+ }
- return lenCompare;
+ /**
+ * @return debug string
+ */
+ @Override
+ public String toString()
+ {
+ final StringBuilder buf = new StringBuilder();
+ buf.append( "[DED: " );
+ buf.append( " pos = " + pos );
+ buf.append( " len = " + len );
+ buf.append( "]" );
+ return buf.toString();
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCache.java
index b3a80c46..f28b562c 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCache.java
@@ -125,37 +125,249 @@ public class JDBCDiskCache<K, V>
}
/**
- * Inserts or updates. By default it will try to insert. If the item exists we will get an
- * error. It will then update. This behavior is configurable. The cache can be configured to
- * check before inserting.
- * <p>
- * @param ce
+ * @param pattern
+ * @return String to use in the like query.
*/
- @Override
- protected void processUpdate( final ICacheElement<K, V> ce )
+ public String constructLikeParameterFromPattern( final String pattern )
{
- updateCount.incrementAndGet();
+ String likePattern = pattern.replace( ".+", "%" );
+ likePattern = likePattern.replace( ".", "_" );
- log.debug( "updating, ce = {0}", ce );
+ log.debug( "pattern = [{0}]", likePattern );
+
+ return likePattern;
+ }
+
+ /**
+ * Removed the expired. (now - create time) > max life seconds * 1000
+ * <p>
+ * @return the number deleted
+ */
+ protected int deleteExpired()
+ {
+ int deleted = 0;
try (Connection con = getDataSource().getConnection())
{
- log.debug( "Putting [{0}] on disk.", ce::getKey);
+ // The shrinker thread might kick in before the table is created
+ // So check if the table exists first
+ final DatabaseMetaData dmd = con.getMetaData();
+ final ResultSet result = dmd.getTables(null, null,
+ getJdbcDiskCacheAttributes().getTableName(), null);
- try
+ if (result.next())
{
- final byte[] element = getElementSerializer().serialize( ce );
- insertOrUpdate( ce, con, element );
+ getTableState().setState( TableState.DELETE_RUNNING );
+ final long now = System.currentTimeMillis() / 1000;
+
+ final String sql = String.format("delete from %s where IS_ETERNAL = ? and REGION = ?"
+ + " and ? > SYSTEM_EXPIRE_TIME_SECONDS", getJdbcDiskCacheAttributes().getTableName());
+
+ try (PreparedStatement psDelete = con.prepareStatement( sql ))
+ {
+ psDelete.setString( 1, "F" );
+ psDelete.setString( 2, this.getCacheName() );
+ psDelete.setLong( 3, now );
+
+ setAlive(true);
+
+ deleted = psDelete.executeUpdate();
+ }
+ catch ( final SQLException e )
+ {
+ log.error( "Problem creating statement.", e );
+ setAlive(false);
+ }
+
+ logApplicationEvent( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
+ "Deleted expired elements. URL: " + getDiskLocation() );
}
- catch ( final IOException e )
+ else
{
- log.error( "Could not serialize element", e );
+ log.warn( "Trying to shrink non-existing table [{0}]",
+ getJdbcDiskCacheAttributes().getTableName() );
}
}
catch ( final SQLException e )
{
- log.error( "Problem getting connection.", e );
+ logError( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
+ e.getMessage() + " URL: " + getDiskLocation() );
+ log.error( "Problem removing expired elements from the table.", e );
+ reset();
+ }
+ finally
+ {
+ getTableState().setState( TableState.FREE );
+ }
+
+ return deleted;
+ }
+
+ /**
+ * Does an element exist for this key?
+ * <p>
+ * @param ce the cache element
+ * @param con a database connection
+ * @return boolean
+ */
+ protected boolean doesElementExist( final ICacheElement<K, V> ce, final Connection con )
+ {
+ boolean exists = false;
+ // don't select the element, since we want this to be fast.
+ final String sqlS = String.format("select CACHE_KEY from %s where REGION = ? and CACHE_KEY = ?",
+ getJdbcDiskCacheAttributes().getTableName());
+
+ try (PreparedStatement psSelect = con.prepareStatement( sqlS ))
+ {
+ psSelect.setString( 1, this.getCacheName() );
+ psSelect.setString( 2, (String) ce.getKey() );
+
+ try (ResultSet rs = psSelect.executeQuery())
+ {
+ exists = rs.next();
+ }
+
+ log.debug( "[{0}] existing status is {1}", ce.getKey(), exists );
+ }
+ catch ( final SQLException e )
+ {
+ log.error( "Problem looking for item before insert.", e );
+ }
+
+ return exists;
+ }
+
+ /**
+ * @return Returns the AuxiliaryCacheAttributes.
+ */
+ @Override
+ public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+ {
+ return this.getJdbcDiskCacheAttributes();
+ }
+
+ /**
+ * Public so managers can access it.
+ * @return the dsFactory
+ * @throws SQLException if getting a data source fails
+ */
+ public DataSource getDataSource() throws SQLException
+ {
+ return dsFactory.getDataSource();
+ }
+
+ /**
+ * This is used by the event logging.
+ * <p>
+ * @return the location of the disk, either path or ip.
+ */
+ @Override
+ protected String getDiskLocation()
+ {
+ return this.jdbcDiskCacheAttributes.getUrl();
+ }
+
+ /**
+ * @return Returns the jdbcDiskCacheAttributes.
+ */
+ protected JDBCDiskCacheAttributes getJdbcDiskCacheAttributes()
+ {
+ return jdbcDiskCacheAttributes;
+ }
+
+ /**
+ * Return the keys in this cache.
+ * <p>
+ * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#getKeySet()
+ */
+ @Override
+ public Set<K> getKeySet() throws IOException
+ {
+ throw new UnsupportedOperationException( "Groups not implemented." );
+ // return null;
+ }
+
+ /**
+ * Returns the current cache size. Just does a count(*) for the region.
+ * <p>
+ * @return The size value
+ */
+ @Override
+ public int getSize()
+ {
+ int size = 0;
+
+ // region, key
+ final String selectString = String.format("select count(*) from %s where REGION = ?",
+ getJdbcDiskCacheAttributes().getTableName());
+
+ try (Connection con = getDataSource().getConnection())
+ {
+ try (PreparedStatement psSelect = con.prepareStatement( selectString ))
+ {
+ psSelect.setString( 1, this.getCacheName() );
+
+ try (ResultSet rs = psSelect.executeQuery())
+ {
+ if ( rs.next() )
+ {
+ size = rs.getInt( 1 );
+ }
+ }
+ }
+ }
+ catch ( final SQLException e )
+ {
+ log.error( "Problem getting size.", e );
}
+
+ return size;
+ }
+
+ /**
+ * Extends the parent stats.
+ * <p>
+ * @return IStats
+ */
+ @Override
+ public IStats getStatistics()
+ {
+ final IStats stats = super.getStatistics();
+ stats.setTypeName( "JDBC/Abstract Disk Cache" );
+
+ final List<IStatElement<?>> elems = stats.getStatElements();
+
+ elems.add(new StatElement<>( "Update Count", updateCount ) );
+ elems.add(new StatElement<>( "Get Count", getCount ) );
+ elems.add(new StatElement<>( "Get Matching Count", getMatchingCount ) );
+ elems.add(new StatElement<>( "DB URL", getJdbcDiskCacheAttributes().getUrl()) );
+
+ stats.setStatElements( elems );
+
+ return stats;
+ }
+
+ /**
+ * Returns the name of the table.
+ * <p>
+ * @return the table name or UNDEFINED
+ */
+ protected String getTableName()
+ {
+ String name = "UNDEFINED";
+ if ( this.getJdbcDiskCacheAttributes() != null )
+ {
+ name = this.getJdbcDiskCacheAttributes().getTableName();
+ }
+ return name;
+ }
+
+ /**
+ * @return Returns the tableState.
+ */
+ public TableState getTableState()
+ {
+ return tableState;
}
/**
@@ -247,78 +459,24 @@ public class JDBCDiskCache<K, V>
return exists;
}
- /**
- * This updates a row in the database.
- * <p>
- * @param ce
- * @param con
- * @param element
- */
- private void updateRow( final ICacheElement<K, V> ce, final Connection con, final byte[] element )
+ /** Shuts down the pool */
+ @Override
+ public void processDispose()
{
- final String sqlU = String.format("""
- update %s\
- set ELEMENT = ?, CREATE_TIME = ?, UPDATE_TIME_SECONDS = ?,\s\
- SYSTEM_EXPIRE_TIME_SECONDS = ?\s\
- where CACHE_KEY = ? and REGION = ?""", getJdbcDiskCacheAttributes().getTableName());
+ final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), null, ICacheEventLogger.DISPOSE_EVENT );
- try (PreparedStatement psUpdate = con.prepareStatement( sqlU ))
+ try
{
- psUpdate.setBytes( 1, element );
-
- final Timestamp createTime = new Timestamp( ce.getElementAttributes().getCreateTime() );
- psUpdate.setTimestamp( 2, createTime );
-
- final long now = System.currentTimeMillis() / 1000;
- psUpdate.setLong( 3, now );
-
- final long expireTime = now + ce.getElementAttributes().getMaxLife();
- psUpdate.setLong( 4, expireTime );
-
- psUpdate.setString( 5, (String) ce.getKey() );
- psUpdate.setString( 6, this.getCacheName() );
- psUpdate.execute();
-
- log.debug( "ran update {0}", sqlU );
+ dsFactory.close();
}
catch ( final SQLException e )
{
- log.error( "Error executing update sql [{0}]", sqlU, e );
- }
- }
-
- /**
- * Does an element exist for this key?
- * <p>
- * @param ce the cache element
- * @param con a database connection
- * @return boolean
- */
- protected boolean doesElementExist( final ICacheElement<K, V> ce, final Connection con )
- {
- boolean exists = false;
- // don't select the element, since we want this to be fast.
- final String sqlS = String.format("select CACHE_KEY from %s where REGION = ? and CACHE_KEY = ?",
- getJdbcDiskCacheAttributes().getTableName());
-
- try (PreparedStatement psSelect = con.prepareStatement( sqlS ))
- {
- psSelect.setString( 1, this.getCacheName() );
- psSelect.setString( 2, (String) ce.getKey() );
-
- try (ResultSet rs = psSelect.executeQuery())
- {
- exists = rs.next();
- }
-
- log.debug( "[{0}] existing status is {1}", ce.getKey(), exists );
+ log.error( "Problem shutting down.", e );
}
- catch ( final SQLException e )
+ finally
{
- log.error( "Problem looking for item before insert.", e );
+ logICacheEvent( cacheEvent );
}
-
- return exists;
}
/**
@@ -437,30 +595,16 @@ public class JDBCDiskCache<K, V>
}
}
}
- }
- }
- }
- catch ( final SQLException sqle )
- {
- log.error( "Caught a SQL exception trying to get items for pattern [{0}]",
- pattern, sqle );
- }
-
- return results;
- }
-
- /**
- * @param pattern
- * @return String to use in the like query.
- */
- public String constructLikeParameterFromPattern( final String pattern )
- {
- String likePattern = pattern.replace( ".+", "%" );
- likePattern = likePattern.replace( ".", "_" );
-
- log.debug( "pattern = [{0}]", likePattern );
+ }
+ }
+ }
+ catch ( final SQLException sqle )
+ {
+ log.error( "Caught a SQL exception trying to get items for pattern [{0}]",
+ pattern, sqle );
+ }
- return likePattern;
+ return results;
}
/**
@@ -556,68 +700,37 @@ public class JDBCDiskCache<K, V>
}
/**
- * Removed the expired. (now - create time) > max life seconds * 1000
+ * Inserts or updates. By default it will try to insert. If the item exists we will get an
+ * error. It will then update. This behavior is configurable. The cache can be configured to
+ * check before inserting.
* <p>
- * @return the number deleted
+ * @param ce
*/
- protected int deleteExpired()
+ @Override
+ protected void processUpdate( final ICacheElement<K, V> ce )
{
- int deleted = 0;
+ updateCount.incrementAndGet();
+
+ log.debug( "updating, ce = {0}", ce );
try (Connection con = getDataSource().getConnection())
{
- // The shrinker thread might kick in before the table is created
- // So check if the table exists first
- final DatabaseMetaData dmd = con.getMetaData();
- final ResultSet result = dmd.getTables(null, null,
- getJdbcDiskCacheAttributes().getTableName(), null);
+ log.debug( "Putting [{0}] on disk.", ce::getKey);
- if (result.next())
+ try
{
- getTableState().setState( TableState.DELETE_RUNNING );
- final long now = System.currentTimeMillis() / 1000;
-
- final String sql = String.format("delete from %s where IS_ETERNAL = ? and REGION = ?"
- + " and ? > SYSTEM_EXPIRE_TIME_SECONDS", getJdbcDiskCacheAttributes().getTableName());
-
- try (PreparedStatement psDelete = con.prepareStatement( sql ))
- {
- psDelete.setString( 1, "F" );
- psDelete.setString( 2, this.getCacheName() );
- psDelete.setLong( 3, now );
-
- setAlive(true);
-
- deleted = psDelete.executeUpdate();
- }
- catch ( final SQLException e )
- {
- log.error( "Problem creating statement.", e );
- setAlive(false);
- }
-
- logApplicationEvent( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
- "Deleted expired elements. URL: " + getDiskLocation() );
+ final byte[] element = getElementSerializer().serialize( ce );
+ insertOrUpdate( ce, con, element );
}
- else
+ catch ( final IOException e )
{
- log.warn( "Trying to shrink non-existing table [{0}]",
- getJdbcDiskCacheAttributes().getTableName() );
+ log.error( "Could not serialize element", e );
}
}
catch ( final SQLException e )
{
- logError( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
- e.getMessage() + " URL: " + getDiskLocation() );
- log.error( "Problem removing expired elements from the table.", e );
- reset();
- }
- finally
- {
- getTableState().setState( TableState.FREE );
+ log.error( "Problem getting connection.", e );
}
-
- return deleted;
}
/**
@@ -628,75 +741,6 @@ public class JDBCDiskCache<K, V>
// nothing
}
- /** Shuts down the pool */
- @Override
- public void processDispose()
- {
- final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), null, ICacheEventLogger.DISPOSE_EVENT );
-
- try
- {
- dsFactory.close();
- }
- catch ( final SQLException e )
- {
- log.error( "Problem shutting down.", e );
- }
- finally
- {
- logICacheEvent( cacheEvent );
- }
- }
-
- /**
- * Returns the current cache size. Just does a count(*) for the region.
- * <p>
- * @return The size value
- */
- @Override
- public int getSize()
- {
- int size = 0;
-
- // region, key
- final String selectString = String.format("select count(*) from %s where REGION = ?",
- getJdbcDiskCacheAttributes().getTableName());
-
- try (Connection con = getDataSource().getConnection())
- {
- try (PreparedStatement psSelect = con.prepareStatement( selectString ))
- {
- psSelect.setString( 1, this.getCacheName() );
-
- try (ResultSet rs = psSelect.executeQuery())
- {
- if ( rs.next() )
- {
- size = rs.getInt( 1 );
- }
- }
- }
- }
- catch ( final SQLException e )
- {
- log.error( "Problem getting size.", e );
- }
-
- return size;
- }
-
- /**
- * Return the keys in this cache.
- * <p>
- * @see org.apache.commons.jcs3.auxiliary.disk.AbstractDiskCache#getKeySet()
- */
- @Override
- public Set<K> getKeySet() throws IOException
- {
- throw new UnsupportedOperationException( "Groups not implemented." );
- // return null;
- }
-
/**
* @param jdbcDiskCacheAttributes The jdbcDiskCacheAttributes to set.
*/
@@ -706,105 +750,61 @@ public class JDBCDiskCache<K, V>
}
/**
- * @return Returns the jdbcDiskCacheAttributes.
- */
- protected JDBCDiskCacheAttributes getJdbcDiskCacheAttributes()
- {
- return jdbcDiskCacheAttributes;
- }
-
- /**
- * @return Returns the AuxiliaryCacheAttributes.
+ * @param tableState The tableState to set.
*/
- @Override
- public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+ public void setTableState( final TableState tableState )
{
- return this.getJdbcDiskCacheAttributes();
+ this.tableState = tableState;
}
/**
- * Extends the parent stats.
+ * For debugging.
* <p>
- * @return IStats
+ * @return this.getStats();
*/
@Override
- public IStats getStatistics()
+ public String toString()
{
- final IStats stats = super.getStatistics();
- stats.setTypeName( "JDBC/Abstract Disk Cache" );
-
- final List<IStatElement<?>> elems = stats.getStatElements();
-
- elems.add(new StatElement<>( "Update Count", updateCount ) );
- elems.add(new StatElement<>( "Get Count", getCount ) );
- elems.add(new StatElement<>( "Get Matching Count", getMatchingCount ) );
- elems.add(new StatElement<>( "DB URL", getJdbcDiskCacheAttributes().getUrl()) );
-
- stats.setStatElements( elems );
-
- return stats;
+ return this.getStats();
}
/**
- * Returns the name of the table.
+ * This updates a row in the database.
* <p>
- * @return the table name or UNDEFINED
+ * @param ce
+ * @param con
+ * @param element
*/
- protected String getTableName()
+ private void updateRow( final ICacheElement<K, V> ce, final Connection con, final byte[] element )
{
- String name = "UNDEFINED";
- if ( this.getJdbcDiskCacheAttributes() != null )
+ final String sqlU = String.format("""
+ update %s\
+ set ELEMENT = ?, CREATE_TIME = ?, UPDATE_TIME_SECONDS = ?,\s\
+ SYSTEM_EXPIRE_TIME_SECONDS = ?\s\
+ where CACHE_KEY = ? and REGION = ?""", getJdbcDiskCacheAttributes().getTableName());
+
+ try (PreparedStatement psUpdate = con.prepareStatement( sqlU ))
{
- name = this.getJdbcDiskCacheAttributes().getTableName();
- }
- return name;
- }
+ psUpdate.setBytes( 1, element );
- /**
- * @param tableState The tableState to set.
- */
- public void setTableState( final TableState tableState )
- {
- this.tableState = tableState;
- }
+ final Timestamp createTime = new Timestamp( ce.getElementAttributes().getCreateTime() );
+ psUpdate.setTimestamp( 2, createTime );
- /**
- * @return Returns the tableState.
- */
- public TableState getTableState()
- {
- return tableState;
- }
+ final long now = System.currentTimeMillis() / 1000;
+ psUpdate.setLong( 3, now );
- /**
- * This is used by the event logging.
- * <p>
- * @return the location of the disk, either path or ip.
- */
- @Override
- protected String getDiskLocation()
- {
- return this.jdbcDiskCacheAttributes.getUrl();
- }
+ final long expireTime = now + ce.getElementAttributes().getMaxLife();
+ psUpdate.setLong( 4, expireTime );
- /**
- * Public so managers can access it.
- * @return the dsFactory
- * @throws SQLException if getting a data source fails
- */
- public DataSource getDataSource() throws SQLException
- {
- return dsFactory.getDataSource();
- }
+ psUpdate.setString( 5, (String) ce.getKey() );
+ psUpdate.setString( 6, this.getCacheName() );
+ psUpdate.execute();
- /**
- * For debugging.
- * <p>
- * @return this.getStats();
- */
- @Override
- public String toString()
- {
- return this.getStats();
+ log.debug( "ran update {0}", sqlU );
+ }
+ catch ( final SQLException e )
+ {
+ log.error( "Error executing update sql [{0}]", sqlU, e );
+ }
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java
index eb015c31..8e6246b0 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java
@@ -33,6 +33,15 @@ public class JDBCDiskCacheAttributes
/** default */
private static final String DEFAULT_TABLE_NAME = "JCS_STORE";
+ /** This is the default limit on the maximum number of active connections. */
+ public static final int DEFAULT_MAX_TOTAL = 10;
+
+ /** This is the default setting for the cleanup routine. */
+ public static final int DEFAULT_SHRINKER_INTERVAL_SECONDS = 300;
+
+ /** The default Pool Name to which the connection pool will be keyed. */
+ public static final String DEFAULT_POOL_NAME = "jcs";
+
/** DB username */
private String userName;
@@ -60,24 +69,15 @@ public class JDBCDiskCacheAttributes
/** If false we will insert and if it fails we will update. */
private boolean testBeforeInsert = true;
- /** This is the default limit on the maximum number of active connections. */
- public static final int DEFAULT_MAX_TOTAL = 10;
-
/** Max connections allowed */
private int maxTotal = DEFAULT_MAX_TOTAL;
- /** This is the default setting for the cleanup routine. */
- public static final int DEFAULT_SHRINKER_INTERVAL_SECONDS = 300;
-
/** How often should we remove expired. */
private int shrinkerIntervalSeconds = DEFAULT_SHRINKER_INTERVAL_SECONDS;
/** Should we remove expired in the background. */
private boolean useDiskShrinker = true;
- /** The default Pool Name to which the connection pool will be keyed. */
- public static final String DEFAULT_POOL_NAME = "jcs";
-
/**
* If a pool name is supplied, the manager will attempt to load it. It should be configured in a
* separate section as follows. Assuming the name is "MyPool":
@@ -93,27 +93,51 @@ public class JDBCDiskCacheAttributes
private String connectionPoolName;
/**
- * @param userName The userName to set.
+ * @return the connectionPoolName
*/
- public void setUserName( final String userName )
+ public String getConnectionPoolName()
{
- this.userName = userName;
+ return connectionPoolName;
}
/**
- * @return Returns the userName.
+ * @return Returns the database.
*/
- public String getUserName()
+ public String getDatabase()
{
- return userName;
+ return database;
}
/**
- * @param password The password to set.
+ * @return Returns the driverClassName.
*/
- public void setPassword( final String password )
+ public String getDriverClassName()
{
- this.password = password;
+ return driverClassName;
+ }
+
+ /**
+ * @return the jndiPath
+ */
+ public String getJndiPath()
+ {
+ return jndiPath;
+ }
+
+ /**
+ * @return the jndiTTL
+ */
+ public long getJndiTTL()
+ {
+ return jndiTTL;
+ }
+
+ /**
+ * @return Returns the maxTotal.
+ */
+ public int getMaxTotal()
+ {
+ return maxTotal;
}
/**
@@ -125,11 +149,19 @@ public class JDBCDiskCacheAttributes
}
/**
- * @param url The url to set.
+ * @return Returns the shrinkerIntervalSeconds.
*/
- public void setUrl( final String url )
+ public int getShrinkerIntervalSeconds()
{
- this.url = url;
+ return shrinkerIntervalSeconds;
+ }
+
+ /**
+ * @return Returns the tableName.
+ */
+ public String getTableName()
+ {
+ return tableName;
}
/**
@@ -141,47 +173,55 @@ public class JDBCDiskCacheAttributes
}
/**
- * This is appended to the url.
- * @param database The database to set.
+ * @return Returns the userName.
*/
- public void setDatabase( final String database )
+ public String getUserName()
{
- this.database = database;
+ return userName;
}
- /**
- * @return Returns the database.
+ /**
+ * @return Returns the testBeforeInsert.
*/
- public String getDatabase()
+ public boolean isTestBeforeInsert()
{
- return database;
+ return testBeforeInsert;
}
- /**
- * @param driverClassName The driverClassName to set.
+ /**
+ * @return Returns the useDiskShrinker.
*/
- public void setDriverClassName( final String driverClassName )
+ public boolean isUseDiskShrinker()
{
- this.driverClassName = driverClassName;
+ return useDiskShrinker;
}
- /**
- * @return Returns the driverClassName.
+ /**
+ * @param connectionPoolName the connectionPoolName to set
*/
- public String getDriverClassName()
+ public void setConnectionPoolName( final String connectionPoolName )
{
- return driverClassName;
+ this.connectionPoolName = connectionPoolName;
+ }
+
+ /**
+ * This is appended to the url.
+ * @param database The database to set.
+ */
+ public void setDatabase( final String database )
+ {
+ this.database = database;
}
/**
- * @return the jndiPath
- */
- public String getJndiPath()
- {
- return jndiPath;
- }
+ * @param driverClassName The driverClassName to set.
+ */
+ public void setDriverClassName( final String driverClassName )
+ {
+ this.driverClassName = driverClassName;
+ }
- /**
+ /**
* @param jndiPath the jndiPath to set
*/
public void setJndiPath(final String jndiPath)
@@ -189,15 +229,7 @@ public class JDBCDiskCacheAttributes
this.jndiPath = jndiPath;
}
- /**
- * @return the jndiTTL
- */
- public long getJndiTTL()
- {
- return jndiTTL;
- }
-
- /**
+ /**
* @param jndiTTL the jndiTTL to set
*/
public void setJndiTTL(final long jndiTTL)
@@ -205,41 +237,6 @@ public class JDBCDiskCacheAttributes
this.jndiTTL = jndiTTL;
}
- /**
- * @param tableName The tableName to set.
- */
- public void setTableName( final String tableName )
- {
- this.tableName = tableName;
- }
-
- /**
- * @return Returns the tableName.
- */
- public String getTableName()
- {
- return tableName;
- }
-
- /**
- * If this is true then the disk cache will check to see if the item already exists in the
- * database. If it is false, it will try to insert. If the insert fails it will try to update.
- * <p>
- * @param testBeforeInsert The testBeforeInsert to set.
- */
- public void setTestBeforeInsert( final boolean testBeforeInsert )
- {
- this.testBeforeInsert = testBeforeInsert;
- }
-
- /**
- * @return Returns the testBeforeInsert.
- */
- public boolean isTestBeforeInsert()
- {
- return testBeforeInsert;
- }
-
/**
* @param maxActive The maxTotal to set.
*/
@@ -249,11 +246,11 @@ public class JDBCDiskCacheAttributes
}
/**
- * @return Returns the maxTotal.
+ * @param password The password to set.
*/
- public int getMaxTotal()
+ public void setPassword( final String password )
{
- return maxTotal;
+ this.password = password;
}
/**
@@ -265,43 +262,46 @@ public class JDBCDiskCacheAttributes
}
/**
- * @return Returns the shrinkerIntervalSeconds.
+ * @param tableName The tableName to set.
*/
- public int getShrinkerIntervalSeconds()
+ public void setTableName( final String tableName )
{
- return shrinkerIntervalSeconds;
+ this.tableName = tableName;
}
/**
- * @param useDiskShrinker The useDiskShrinker to set.
+ * If this is true then the disk cache will check to see if the item already exists in the
+ * database. If it is false, it will try to insert. If the insert fails it will try to update.
+ * <p>
+ * @param testBeforeInsert The testBeforeInsert to set.
*/
- public void setUseDiskShrinker( final boolean useDiskShrinker )
+ public void setTestBeforeInsert( final boolean testBeforeInsert )
{
- this.useDiskShrinker = useDiskShrinker;
+ this.testBeforeInsert = testBeforeInsert;
}
/**
- * @return Returns the useDiskShrinker.
+ * @param url The url to set.
*/
- public boolean isUseDiskShrinker()
+ public void setUrl( final String url )
{
- return useDiskShrinker;
+ this.url = url;
}
/**
- * @param connectionPoolName the connectionPoolName to set
+ * @param useDiskShrinker The useDiskShrinker to set.
*/
- public void setConnectionPoolName( final String connectionPoolName )
+ public void setUseDiskShrinker( final boolean useDiskShrinker )
{
- this.connectionPoolName = connectionPoolName;
+ this.useDiskShrinker = useDiskShrinker;
}
/**
- * @return the connectionPoolName
+ * @param userName The userName to set.
*/
- public String getConnectionPoolName()
+ public void setUserName( final String userName )
{
- return connectionPoolName;
+ this.userName = userName;
}
/**
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
index 847d1c43..f68951f3 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
@@ -49,6 +49,12 @@ public class JDBCDiskCacheFactory
/** The logger */
private static final Log log = LogManager.getLog( JDBCDiskCacheFactory.class );
+ /** props prefix */
+ protected static final String POOL_CONFIGURATION_PREFIX = "jcs.jdbcconnectionpool.";
+
+ /** .attributes */
+ protected static final String ATTRIBUTE_PREFIX = ".attributes";
+
/**
* A map of TableState objects to table names. Each cache has a table state object, which is
* used to determine if any long processes such as deletes or optimizations are running.
@@ -67,12 +73,6 @@ public class JDBCDiskCacheFactory
/** Pool name to DataSourceFactories */
private ConcurrentMap<String, DataSourceFactory> dsFactories;
- /** props prefix */
- protected static final String POOL_CONFIGURATION_PREFIX = "jcs.jdbcconnectionpool.";
-
- /** .attributes */
- protected static final String ATTRIBUTE_PREFIX = ".attributes";
-
/**
* This factory method should create an instance of the jdbc cache.
* <p>
@@ -104,15 +104,30 @@ public class JDBCDiskCacheFactory
}
/**
- * Initialize this factory
+ * If UseDiskShrinker is true then we will create a shrinker daemon if necessary.
+ * <p>
+ * @param cattr
+ * @param raf
*/
- @Override
- public void initialize()
+ protected void createShrinkerWhenNeeded( final JDBCDiskCacheAttributes cattr, final JDBCDiskCache<?, ?> raf )
{
- super.initialize();
- this.tableStates = new ConcurrentHashMap<>();
- this.shrinkerThreadMap = new ConcurrentHashMap<>();
- this.dsFactories = new ConcurrentHashMap<>();
+ // add cache to shrinker.
+ if ( cattr.isUseDiskShrinker() )
+ {
+ final ScheduledExecutorService shrinkerService = getScheduledExecutorService();
+ final ShrinkerThread shrinkerThread = shrinkerThreadMap.computeIfAbsent(cattr.getTableName(), key -> {
+ final ShrinkerThread newShrinkerThread = new ShrinkerThread();
+
+ final long intervalMillis = Math.max( 999, cattr.getShrinkerIntervalSeconds() * 1000 );
+ log.info( "Setting the shrinker to run every [{0}] ms. for table [{1}]",
+ intervalMillis, key );
+ shrinkerService.scheduleAtFixedRate(newShrinkerThread, 0, intervalMillis, TimeUnit.MILLISECONDS);
+
+ return newShrinkerThread;
+ });
+
+ shrinkerThread.addDiskCacheToShrinkList( raf );
+ }
}
/**
@@ -140,63 +155,6 @@ public class JDBCDiskCacheFactory
super.dispose();
}
- /**
- * Gets a table state for a given table name
- *
- * @param tableName
- * @return a cached instance of the table state
- */
- protected TableState getTableState(final String tableName)
- {
- return tableStates.computeIfAbsent(tableName, TableState::new);
- }
-
- /**
- * @see org.apache.commons.jcs3.engine.behavior.IRequireScheduler#setScheduledExecutorService(java.util.concurrent.ScheduledExecutorService)
- */
- @Override
- public void setScheduledExecutorService(final ScheduledExecutorService scheduledExecutor)
- {
- this.scheduler = scheduledExecutor;
- }
-
- /**
- * Gets the scheduler service
- *
- * @return the scheduler
- */
- protected ScheduledExecutorService getScheduledExecutorService()
- {
- return scheduler;
- }
-
- /**
- * If UseDiskShrinker is true then we will create a shrinker daemon if necessary.
- * <p>
- * @param cattr
- * @param raf
- */
- protected void createShrinkerWhenNeeded( final JDBCDiskCacheAttributes cattr, final JDBCDiskCache<?, ?> raf )
- {
- // add cache to shrinker.
- if ( cattr.isUseDiskShrinker() )
- {
- final ScheduledExecutorService shrinkerService = getScheduledExecutorService();
- final ShrinkerThread shrinkerThread = shrinkerThreadMap.computeIfAbsent(cattr.getTableName(), key -> {
- final ShrinkerThread newShrinkerThread = new ShrinkerThread();
-
- final long intervalMillis = Math.max( 999, cattr.getShrinkerIntervalSeconds() * 1000 );
- log.info( "Setting the shrinker to run every [{0}] ms. for table [{1}]",
- intervalMillis, key );
- shrinkerService.scheduleAtFixedRate(newShrinkerThread, 0, intervalMillis, TimeUnit.MILLISECONDS);
-
- return newShrinkerThread;
- });
-
- shrinkerThread.addDiskCacheToShrinkList( raf );
- }
- }
-
/**
* manages the DataSourceFactories.
* <p>
@@ -259,4 +217,46 @@ public class JDBCDiskCacheFactory
return newDsFactory;
});
}
+
+ /**
+ * Gets the scheduler service
+ *
+ * @return the scheduler
+ */
+ protected ScheduledExecutorService getScheduledExecutorService()
+ {
+ return scheduler;
+ }
+
+ /**
+ * Gets a table state for a given table name
+ *
+ * @param tableName
+ * @return a cached instance of the table state
+ */
+ protected TableState getTableState(final String tableName)
+ {
+ return tableStates.computeIfAbsent(tableName, TableState::new);
+ }
+
+ /**
+ * Initialize this factory
+ */
+ @Override
+ public void initialize()
+ {
+ super.initialize();
+ this.tableStates = new ConcurrentHashMap<>();
+ this.shrinkerThreadMap = new ConcurrentHashMap<>();
+ this.dsFactories = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * @see org.apache.commons.jcs3.engine.behavior.IRequireScheduler#setScheduledExecutorService(java.util.concurrent.ScheduledExecutorService)
+ */
+ @Override
+ public void setScheduledExecutorService(final ScheduledExecutorService scheduledExecutor)
+ {
+ this.scheduler = scheduledExecutor;
+ }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/ShrinkerThread.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/ShrinkerThread.java
index 6068433e..10a24624 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/ShrinkerThread.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/ShrinkerThread.java
@@ -36,13 +36,13 @@ public class ShrinkerThread
/** The logger. */
private static final Log log = LogManager.getLog( ShrinkerThread.class );
+ /** Default time period to use. */
+ private static final long DEFAULT_PAUSE_BETWEEN_REGION_CALLS_MILLIS = 5000;
+
/** A set of JDBCDiskCache objects to call deleteExpired on. */
private final CopyOnWriteArraySet<JDBCDiskCache<?, ?>> shrinkSet =
new CopyOnWriteArraySet<>();
- /** Default time period to use. */
- private static final long DEFAULT_PAUSE_BETWEEN_REGION_CALLS_MILLIS = 5000;
-
/**
* How long should we wait between calls to deleteExpired when we are iterating through the list
* of regions. Delete can lock the table. We want to give clients a chance to get some work
@@ -71,22 +71,6 @@ public class ShrinkerThread
shrinkSet.add( diskCache );
}
- /**
- * Calls deleteExpired on each item in the set. It pauses between each call.
- */
- @Override
- public void run()
- {
- try
- {
- deleteExpiredFromAllRegisteredRegions();
- }
- catch ( final Throwable e )
- {
- log.error( "Caught an exception while trying to delete expired items.", e );
- }
- }
-
/**
* Deletes the expired items from all the registered regions.
*/
@@ -126,21 +110,37 @@ public class ShrinkerThread
* How long should we wait between calls to deleteExpired when we are iterating through the list
* of regions.
* <p>
- * @param pauseBetweenRegionCallsMillis The pauseBetweenRegionCallsMillis to set.
+ * @return Returns the pauseBetweenRegionCallsMillis.
*/
- public void setPauseBetweenRegionCallsMillis( final long pauseBetweenRegionCallsMillis )
+ public long getPauseBetweenRegionCallsMillis()
{
- this.pauseBetweenRegionCallsMillis = pauseBetweenRegionCallsMillis;
+ return pauseBetweenRegionCallsMillis;
+ }
+
+ /**
+ * Calls deleteExpired on each item in the set. It pauses between each call.
+ */
+ @Override
+ public void run()
+ {
+ try
+ {
+ deleteExpiredFromAllRegisteredRegions();
+ }
+ catch ( final Throwable e )
+ {
+ log.error( "Caught an exception while trying to delete expired items.", e );
+ }
}
/**
* How long should we wait between calls to deleteExpired when we are iterating through the list
* of regions.
* <p>
- * @return Returns the pauseBetweenRegionCallsMillis.
+ * @param pauseBetweenRegionCallsMillis The pauseBetweenRegionCallsMillis to set.
*/
- public long getPauseBetweenRegionCallsMillis()
+ public void setPauseBetweenRegionCallsMillis( final long pauseBetweenRegionCallsMillis )
{
- return pauseBetweenRegionCallsMillis;
+ this.pauseBetweenRegionCallsMillis = pauseBetweenRegionCallsMillis;
}
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/TableState.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/TableState.java
index d169d30f..4b924346 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/TableState.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/TableState.java
@@ -33,9 +33,6 @@ public class TableState
/** Don't change. */
private static final long serialVersionUID = -6625081552084964885L;
- /** Name of the table whose state this reflects. */
- private String tableName;
-
/**
* The table is free. It can be accessed and no potentially table locking
* jobs are running.
@@ -48,6 +45,9 @@ public class TableState
/** A table locking optimization is running. */
public static final int OPTIMIZATION_RUNNING = 2;
+ /** Name of the table whose state this reflects. */
+ private String tableName;
+
/** we might want to add error */
private int state = FREE;
@@ -62,12 +62,11 @@ public class TableState
}
/**
- * @param tableName
- * The tableName to set.
+ * @return Returns the state.
*/
- public void setTableName( final String tableName )
+ public int getState()
{
- this.tableName = tableName;
+ return state;
}
/**
@@ -88,11 +87,12 @@ public class TableState
}
/**
- * @return Returns the state.
+ * @param tableName
+ * The tableName to set.
*/
- public int getState()
+ public void setTableName( final String tableName )
{
- return state;
+ this.tableName = tableName;
}
/**
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/DataSourceFactory.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/DataSourceFactory.java
index eeb9cbf2..9cabf40f 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/DataSourceFactory.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/DataSourceFactory.java
@@ -44,9 +44,19 @@ public interface DataSourceFactory
String FACTORY_KEY = "factory";
/**
- * @return the name of the factory.
+ * A hook which is called when the resources of the associated DataSource
+ * can be released.
+ * After close() is called, the other methods may not work any more
+ * (e.g. getDataSource() might return null).
+ * It is not guaranteed that this method does anything. For example,
+ * we do not want to close connections retrieved via JNDI, so the
+ * JndiDataSouurceFactory does not close these connections
+ *
+ * @throws SQLException Any exceptions caught during processing will be
+ * rethrown wrapped into a SQLException.
*/
- String getName();
+ void close()
+ throws SQLException;
/**
* @return the <code>DataSource</code> configured by the factory.
@@ -55,27 +65,17 @@ public interface DataSourceFactory
DataSource getDataSource() throws SQLException;
/**
- * Initialize the factory.
- *
- * @param config the factory settings
- * @throws SQLException Any exceptions caught during processing will be
- * rethrown wrapped into a SQLException.
+ * @return the name of the factory.
*/
- void initialize(JDBCDiskCacheAttributes config)
- throws SQLException;
+ String getName();
/**
- * A hook which is called when the resources of the associated DataSource
- * can be released.
- * After close() is called, the other methods may not work any more
- * (e.g. getDataSource() might return null).
- * It is not guaranteed that this method does anything. For example,
- * we do not want to close connections retrieved via JNDI, so the
- * JndiDataSouurceFactory does not close these connections
+ * Initialize the factory.
*
+ * @param config the factory settings
* @throws SQLException Any exceptions caught during processing will be
* rethrown wrapped into a SQLException.
*/
- void close()
+ void initialize(JDBCDiskCacheAttributes config)
throws SQLException;
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java
index 2f10a6a3..25dbb7a8 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java
@@ -47,6 +47,20 @@ public class JndiDataSourceFactory implements DataSourceFactory
/** The log. */
private static final Log log = LogManager.getLog(JndiDataSourceFactory.class);
+ /**
+ *
+ * @param ctx the context
+ * @throws NamingException
+ */
+ private static void debugCtx(final Context ctx) throws NamingException
+ {
+ log.trace("InitialContext -------------------------------");
+ final Map<?, ?> env = ctx.getEnvironment();
+ log.trace("Environment properties: {0}", env.size());
+ env.forEach((key, value) -> log.trace(" {0}: {1}", key, value));
+ log.trace("----------------------------------------------");
+ }
+
/** The name of the factory. */
private String name;
@@ -66,12 +80,13 @@ public class JndiDataSourceFactory implements DataSourceFactory
private long ttl; // ms
/**
- * @return the name of the factory.
+ * Does nothing. We do not want to close a dataSource retrieved from Jndi,
+ * because other applications might use it as well.
*/
@Override
- public String getName()
+ public void close()
{
- return name;
+ // do nothing
}
/**
@@ -101,6 +116,15 @@ public class JndiDataSourceFactory implements DataSourceFactory
return ds;
}
+ /**
+ * @return the name of the factory.
+ */
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
/**
* @see org.apache.commons.jcs3.auxiliary.disk.jdbc.dsfactory.DataSourceFactory#initialize(JDBCDiskCacheAttributes)
*/
@@ -143,28 +167,4 @@ public class JndiDataSourceFactory implements DataSourceFactory
throw new SQLException(e);
}
}
-
- /**
- * Does nothing. We do not want to close a dataSource retrieved from Jndi,
- * because other applications might use it as well.
- */
- @Override
- public void close()
- {
- // do nothing
- }
-
- /**
- *
- * @param ctx the context
- * @throws NamingException
- */
- private static void debugCtx(final Context ctx) throws NamingException
- {
- log.trace("InitialContext -------------------------------");
- final Map<?, ?> env = ctx.getEnvironment();
- log.trace("Environment properties: {0}", env.size());
- env.forEach((key, value) -> log.trace(" {0}: {1}", key, value));
- log.trace("----------------------------------------------");
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java
index ef7f009d..a5131490 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java
@@ -41,66 +41,6 @@ public class SharedPoolDataSourceFactory implements DataSourceFactory
/** The log. */
private static final Log log = LogManager.getLog(SharedPoolDataSourceFactory.class);
- /** The name of the factory. */
- private String name;
-
- /** The wrapped <code>DataSource</code>. */
- private SharedPoolDataSource ds;
-
- /**
- * @return the name of the factory.
- */
- @Override
- public String getName()
- {
- return name;
- }
-
- /**
- * @see org.apache.commons.jcs3.auxiliary.disk.jdbc.dsfactory.DataSourceFactory#getDataSource()
- */
- @Override
- public DataSource getDataSource()
- {
- return ds;
- }
-
- /**
- * @see org.apache.commons.jcs3.auxiliary.disk.jdbc.dsfactory.DataSourceFactory#initialize(JDBCDiskCacheAttributes)
- */
- @Override
- public void initialize(final JDBCDiskCacheAttributes config) throws SQLException
- {
- this.name = config.getConnectionPoolName();
- final ConnectionPoolDataSource cpds = initCPDS(config);
- final SharedPoolDataSource dataSource = new SharedPoolDataSource();
- initJdbc2Pool(dataSource, config);
- dataSource.setConnectionPoolDataSource(cpds);
- dataSource.setMaxTotal(config.getMaxTotal());
- this.ds = dataSource;
- }
-
- /**
- * Closes the pool associated with this factory and releases it.
- * @throws SQLException if the pool cannot be closed properly
- */
- @Override
- public void close() throws SQLException
- {
- try
- {
- if (ds != null)
- {
- ds.close();
- }
- }
- catch (final Exception e)
- {
- throw new SQLException("Exception caught closing data source", e);
- }
- ds = null;
- }
-
/**
* Initializes the ConnectionPoolDataSource.
*
@@ -146,4 +86,64 @@ public class SharedPoolDataSourceFactory implements DataSourceFactory
dataSource.setDescription(config.getConnectionPoolName());
}
+
+ /** The name of the factory. */
+ private String name;
+
+ /** The wrapped <code>DataSource</code>. */
+ private SharedPoolDataSource ds;
+
+ /**
+ * Closes the pool associated with this factory and releases it.
+ * @throws SQLException if the pool cannot be closed properly
+ */
+ @Override
+ public void close() throws SQLException
+ {
+ try
+ {
+ if (ds != null)
+ {
+ ds.close();
+ }
+ }
+ catch (final Exception e)
+ {
+ throw new SQLException("Exception caught closing data source", e);
+ }
+ ds = null;
+ }
+
+ /**
+ * @see org.apache.commons.jcs3.auxiliary.disk.jdbc.dsfactory.DataSourceFactory#getDataSource()
+ */
+ @Override
+ public DataSource getDataSource()
+ {
+ return ds;
+ }
+
+ /**
+ * @return the name of the factory.
+ */
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * @see org.apache.commons.jcs3.auxiliary.disk.jdbc.dsfactory.DataSourceFactory#initialize(JDBCDiskCacheAttributes)
+ */
+ @Override
+ public void initialize(final JDBCDiskCacheAttributes config) throws SQLException
+ {
+ this.name = config.getConnectionPoolName();
+ final ConnectionPoolDataSource cpds = initCPDS(config);
+ final SharedPoolDataSource dataSource = new SharedPoolDataSource();
+ initJdbc2Pool(dataSource, config);
+ dataSource.setConnectionPoolDataSource(cpds);
+ dataSource.setMaxTotal(config.getMaxTotal());
+ this.ds = dataSource;
+ }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java
index e6bdb8d7..d0601449 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java
@@ -64,6 +64,41 @@ public class MySQLDiskCache<K, V>
log.debug( "MySQLDiskCacheAttributes = {0}", attributes );
}
+ /**
+ * @param pattern
+ * @return String to use in the like query.
+ */
+ @Override
+ public String constructLikeParameterFromPattern( final String pattern )
+ {
+ String likePattern = pattern.replace( ".+", "%" );
+ likePattern = likePattern.replace( ".", "_" );
+
+ log.debug( "pattern = [{0}]", likePattern );
+
+ return likePattern;
+ }
+
+ /**
+ * Removed the expired. (now - create time) > max life seconds * 1000
+ * <p>
+ * If we are currently optimizing, then this method will balk and do nothing.
+ * <p>
+ * TODO consider blocking and trying again.
+ * <p>
+ * @return the number deleted
+ */
+ @Override
+ protected int deleteExpired()
+ {
+ if (this.getTableState().getState() == TableState.OPTIMIZATION_RUNNING &&
+ this.mySQLDiskCacheAttributes.isBalkDuringOptimization())
+ {
+ return -1;
+ }
+ return super.deleteExpired();
+ }
+
/**
* This delegates to the generic JDBC disk cache. If we are currently optimizing, then this
* method will balk and return null.
@@ -100,21 +135,6 @@ public class MySQLDiskCache<K, V>
return super.processGetMatching( pattern );
}
- /**
- * @param pattern
- * @return String to use in the like query.
- */
- @Override
- public String constructLikeParameterFromPattern( final String pattern )
- {
- String likePattern = pattern.replace( ".+", "%" );
- likePattern = likePattern.replace( ".", "_" );
-
- log.debug( "pattern = [{0}]", likePattern );
-
- return likePattern;
- }
-
/**
* This delegates to the generic JDBC disk cache. If we are currently optimizing, then this
* method will balk and do nothing.
@@ -131,24 +151,4 @@ public class MySQLDiskCache<K, V>
}
super.processUpdate( element );
}
-
- /**
- * Removed the expired. (now - create time) > max life seconds * 1000
- * <p>
- * If we are currently optimizing, then this method will balk and do nothing.
- * <p>
- * TODO consider blocking and trying again.
- * <p>
- * @return the number deleted
- */
- @Override
- protected int deleteExpired()
- {
- if (this.getTableState().getState() == TableState.OPTIMIZATION_RUNNING &&
- this.mySQLDiskCacheAttributes.isBalkDuringOptimization())
- {
- return -1;
- }
- return super.deleteExpired();
- }
}
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheAttributes.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheAttributes.java
index b95852ce..594e7e97 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheAttributes.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheAttributes.java
@@ -30,6 +30,11 @@ public class MySQLDiskCacheAttributes
/** Don't change. */
private static final long serialVersionUID = -6535808344813320061L;
+ /**
+ * If true, we will balk, that is return null during optimization rather than block.
+ */
+ public static final boolean DEFAULT_BALK_DURING_OPTIMIZATION = true;
+
/**
* For now this is a simple comma delimited list of HH:MM:SS times to optimize
* the table. If none is supplied, then no optimizations will be performed.
@@ -41,11 +46,6 @@ public class MySQLDiskCacheAttributes
*/
private String optimizationSchedule;
- /**
- * If true, we will balk, that is return null during optimization rather than block.
- */
- public static final boolean DEFAULT_BALK_DURING_OPTIMIZATION = true;
-
/**
* If true, we will balk, that is return null during optimization rather than block.
* <p>
@@ -54,19 +54,21 @@ public class MySQLDiskCacheAttributes
private boolean balkDuringOptimization = DEFAULT_BALK_DURING_OPTIMIZATION;
/**
- * @param optimizationSchedule The optimizationSchedule to set.
+ * @return Returns the optimizationSchedule.
*/
- public void setOptimizationSchedule( final String optimizationSchedule )
+ public String getOptimizationSchedule()
{
- this.optimizationSchedule = optimizationSchedule;
+ return optimizationSchedule;
}
/**
- * @return Returns the optimizationSchedule.
+ * Should we return null while optimizing the table.
+ * <p>
+ * @return Returns the balkDuringOptimization.
*/
- public String getOptimizationSchedule()
+ public boolean isBalkDuringOptimization()
{
- return optimizationSchedule;
+ return balkDuringOptimization;
}
/**
@@ -78,13 +80,11 @@ public class MySQLDiskCacheAttributes
}
/**
- * Should we return null while optimizing the table.
- * <p>
- * @return Returns the balkDuringOptimization.
+ * @param optimizationSchedule The optimizationSchedule to set.
*/
- public boolean isBalkDuringOptimization()
+ public void setOptimizationSchedule( final String optimizationSchedule )
{
- return balkDuringOptimization;
+ this.optimizationSchedule = optimizationSchedule;
}
/**
diff --git a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
index 4e74fc19..1e2768e4 100644
--- a/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
+++ b/commons-jcs3-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
@@ -46,6 +46,22 @@ public class MySQLDiskCacheFactory
/** The logger */
private static final Log log = LogManager.getLog( MySQLDiskCacheFactory.class );
+ /**
+ * This calls the optimizers' optimize table method. This is used by the timer.
+ */
+ private static void optimizeTable(final MySQLTableOptimizer optimizer)
+ {
+ if ( optimizer != null )
+ {
+ final boolean success = optimizer.optimizeTable();
+ log.info( "Optimization success status [{0}]", success );
+ }
+ else
+ {
+ log.warn( "OptimizerRunner: The optimizer is null. Could not optimize table." );
+ }
+ }
+
/**
* This factory method should create an instance of the mysqlcache.
* <p>
@@ -78,6 +94,24 @@ public class MySQLDiskCacheFactory
}
+ /**
+ * This takes in a single time and schedules the optimizer to be called at that time every day.
+ * <p>
... 51886 lines suppressed ...