Implements a cache filter datasource that is capable of caching results of other datesources and distribute them among connected cluster nodes (= 3rd level distributed cache).
Elements, that are kept in the 3rd level cache are actively managed on updates by monitoring what is stored within one site (using clustering). It is safe to assume that cache prunes on updated data reaches each ACL node as multiple ACL nodes build a large virtual cache using UDP based auto-discovery of cluster nodes. (under the assumption clustering was enabled with -DrunClustered=true)
A restart of an ACL node automatically cleans all locally cached information to ensure no old data is kept (disk persistence is primarily used to construct large in-memory and JDBM based caches that offload the SQL-DB).
By actively managing cache prunes on data updates, it is possible to use quite large TTL on data. With the current configuration there's no definite expiration of elements besides from removing elements that are no longer queried. A cache can grow to any size that is required to service requests and is only limited by the amount of available hard disk storage capacity.
Typical cached requests are 10 to 50 times faster when run within the unit test environment (using an indexed in-memory HSQL DB as backend). With the fully loaded GRID DB the differences should be more radical.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | @CacheRegion (name = CacheSettings.CACHE_REGION_FILE_DETAILS, // Using 4% of heap to cache file details (assuming an entry weights 2kb). // At least 250 entries are kept in memory. maxElementsInMemoryExpression = "${max(250, memoryPercent(5) / kb(2))}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = DISTRIBUTE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 6000}" , defaultExpirationTimeUnit = MINUTES), @CacheRegion (name = CacheSettings.CACHE_REGION_FILE_INFORMATION, // Using 15% of heap to cache file information (assuming an entry weights 256b). // At least 250 entries are kept in memory. maxElementsInMemoryExpression = "${max(250, memoryPercent(15) / 256)}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = DISTRIBUTE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 6000}" , defaultExpirationTimeUnit = MINUTES), @CacheRegion (name = CacheSettings.CACHE_REGION_PACKAGE_DETAILS, // Using 2% of heap to cache package details (assuming an entry weights 4kb). // At least 250 entries are kept in memory. maxElementsInMemoryExpression = "${max(250, memoryPercent(3) / kb(4))}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = DISTRIBUTE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 6000}" , defaultExpirationTimeUnit = MINUTES), @CacheRegion (name = CacheSettings.CACHE_REGION_PACKAGE_INFORMATION, // Using 4% of heap to cache package information (assuming an entry weights 512b). // At least 250 entries are kept in memory. maxElementsInMemoryExpression = "${max(250, memoryPercent(5) / 512)}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = DISTRIBUTE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 6000}" , defaultExpirationTimeUnit = MINUTES), @CacheRegion (name = CacheSettings.CACHE_REGION_PACKAGE_FILE_IDENTIFIERS, // Using 2% of heap to cache package name to id mapping (assuming an entry weights 128b). // At least 250 entries are kept in memory. maxElementsInMemoryExpression = "${max(250, memoryPercent(2) / 128)}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = REPLICATE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 6000}" , defaultExpirationTimeUnit = MINUTES), @CacheRegion (name = CacheSettings.CACHE_REGION_UNKNOWN_FILE_IDENTIFIERS, // Using 0.5% of heap to cache unknown identifiers (assuming an entry weights 64b). // At least 512 entries are kept in memory. maxElementsInMemoryExpression = "${max(512, memoryPercent(0.5) / 64)}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = REPLICATE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 120}" , defaultExpirationTimeUnit = MINUTES), @CacheRegion (name = CacheSettings.CACHE_REGION_UNKNOWN_NAMES, // Using 0.5% of heap to cache unknown names (assuming an entry weights 64b). // At least 512 entries are kept in memory. maxElementsInMemoryExpression = "${max(512, memoryPercent(0.5) / 64)}" , persistentMode = TEMPORARY, evictionPolicy = LIRS, distributionPolicy = REPLICATE_VALUES, // Clean entries if not accessed for 6 hours idleTime = 6 , idleTimeUnit = HOURS, // Expire entries after 15 minutes if we're not running clustered or in 'readonly' mode. defaultExpirationTimeExpression = "${not runClustered || readonly ? 15 : 120}" , defaultExpirationTimeUnit = MINUTES) |
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /** * Toggles synchronous cache operations (disabled by default, use if timing issues occur). */ boolean IS_SYNCHRONOUS = Boolean.getBoolean( "gacl.3rdcache.is.synchronous" ); /** * Toggles whether negative ('null') results are cached. */ boolean NO_NEGATIVE_CACHING = Boolean.getBoolean( "gacl.3rdcache.no.negative.caching" ); /** * Toggles whether the batch interface is used for cache operations. */ boolean NO_BATCHING = Boolean.getBoolean( "gacl.3rdcache.no.batching" ); /** * Enables the use of hard disk storage for caching (using JDBM btree format). */ boolean ENABLE_PERSISTENCE = Boolean.getBoolean( "gacl.3rdcache.enable-persistence" ); /** * Toggles whether the 3rd level caching is disabled (temporarily). * <p/> * Note: Disabling the cache with this option does not remove the aspects. * If caching must be disabled permanently to reduce resource usage, the * file 'cache.jar' should be removed from the lib directory. */ boolean DISABLED = Boolean.getBoolean( "gacl.3rdcache.disabled" ); /** * Names the 3rd level cache region that stores FileDetail instances. */ String CACHE_REGION_FILE_DETAILS = "3rdLevel.Cache.FileDetails" ; /** * Names the 3rd level cache region that stores FileInformation instances. */ String CACHE_REGION_FILE_INFORMATION = "3rdLevel.Cache.FileInformation" ; /** * Names the 3rd level cache region that stores PackageDetails instances. */ String CACHE_REGION_PACKAGE_DETAILS = "3rdLevel.Cache.PackageDetails" ; /** * Names the 3rd level cache region that stores PackageInformation instances. */ String CACHE_REGION_PACKAGE_INFORMATION = "3rdLevel.Cache.PackageInformation" ; /** * Names the 3rd level cache region that maps FileIdentifiers against their package names. */ String CACHE_REGION_PACKAGE_FILE_IDENTIFIERS = "Internal.3rdLevel.Cache.PackageFileIdentifiers" ; /** * Names the 3rd level cache region that contains names that are known to be unknown (= negative result caching) */ String CACHE_REGION_UNKNOWN_NAMES = "Internal.3rdLevel.Cache.UnknownNames" ; /** * Names the 3rd level cache region that contains identifiers that are known to be unknown (= negative result caching) */ String CACHE_REGION_UNKNOWN_FILE_IDENTIFIERS = "Internal.3rdLevel.Cache.UnknownFileIdentifiers" ; |
3rd level caching is technically implemented using AspectJ as it requires to intercept and listen at various locations. Using aspects avoids that implementations become intrusive.