@Override public long getCachedBlocks() { return memoryRegion.size(); }
@Override public long getTotalMemoryUsage() { return memoryRegion.memorySize(); }
public <T extends Comparable<T>> void registerRegion(CacheRegion<T, ? extends CacheEntry> region) { regionMap.putIfAbsent(region.name(), region); }
@RequestMapping(value = "/Caches", method = RequestMethod.GET, produces = "application/json") public RestEntity loadModel() throws RestException { GlobalCachingMemoryManager cachingMemoryManager = GlobalCachingMemoryManager.getGlobalInstance(); List<CacheBucket> buckets = new ArrayList<>(); for(CacheRegion region : cachingMemoryManager.getRegions()) { buckets.add(new CacheBucket(region.name(), region.size(), region.memorySize())); } return new CacheBucketCollection(buckets); } }
private CacheRegion<? extends Comparable, ?> getLeastUsedRegion(Set<CacheRegion> checkedRegions) { CacheRegion<? extends Comparable, ?> leastUsed = null; for(CacheRegion<? extends Comparable, ?> region: getRegions()) { LOG.debug("Checking region: {}", region); if(!checkedRegions.contains(region)) { LOG.debug("Region available: {}", region.memorySize()); if(leastUsed == null || leastUsed.lastRegionAccess() > region.lastRegionAccess()) { leastUsed = region; } } } return leastUsed; }
@Override public void writeRecord(UUIDKey documentId, ClonableDataStream dataStream) throws JasDBStorageException { wrappedWriter.writeRecord(documentId, dataStream); String cachingKey = storeName + "_" + documentId.toString(); if(bucket.containsItem(cachingKey)) { bucket.remove(cachingKey); } }
@Override public RecordResult readRecord(UUIDKey documentId) throws JasDBStorageException { String cachingKey = storeName + "_" + documentId.toString(); if(!bucket.containsItem(cachingKey)) { return readRecordFromStore(cachingKey, documentId); } else { log.debug("Cache hit for record: {} key: {}", documentId, cachingKey); CachableRecord cachedRecord = (CachableRecord) bucket.getItem(cachingKey); if(cachedRecord != null) { return cachedRecord.getResult(); } else { return readRecordFromStore(cachingKey, documentId); } } }
@Override public void updateRecord(UUIDKey documentId, ClonableDataStream dataStream) throws JasDBStorageException { wrappedWriter.updateRecord(documentId, dataStream); String cachingKey = storeName + "_" + documentId.toString(); bucket.remove(cachingKey); } }
public void shutdownCacheManager() { for(Bucket bucket : buckets.values()) { bucket.closeBucket(); } buckets.clear(); }
@Override public long memorySize() { lock.lock(); try { long memorySize = 0; for(EntryWrapper entryWrapper : cachedBlocks.values()) { memorySize += entryWrapper.getEntry().memorySize(); } return memorySize; } finally { lock.unlock(); } }
public void flushAndCloseBlock(IndexBlock block) throws JasDBStorageException { persistBlock(block); memoryRegion.removeEntry(block.getPosition()); }
@Override public void flush() throws JasDBStorageException { for(IndexBlockEntry entry : memoryRegion.values()) { IndexBlock block = entry.getValue(); persistBlock(block); } }
@Override public void releaseBlock(IndexBlock block) { memoryRegion.getEntry(block.getPosition()).releaseToken(); }
public void checkMemoryState(Set<CacheRegion> ignoreRegions) { long memorySize = calculateMemorySize(); if(memorySize > maximumMemory) { LOG.debug("Current memory size: {}", memorySize); LOG.debug("Maximum memory: {}", maximumMemory); long reduceSize = memorySize - maximumMemory; LOG.info("Memory overflow: {} bytes more than allowed limit", reduceSize); CacheRegion<? extends Comparable, ?> leastUsed = getLeastUsedRegion(ignoreRegions); if(leastUsed != null) { long actualReduce = leastUsed.reduceBy(reduceSize); LOG.debug("Reduced region: {} by: {} bytes", leastUsed, actualReduce); if(actualReduce < reduceSize) { ignoreRegions.add(leastUsed); LOG.debug("Reduce was not sufficient to meet reduce size: {} was actually: {}", reduceSize, actualReduce); checkMemoryState(ignoreRegions); } } else { LOG.warn("Could not reduce memory footprint further, no more reducable regions available, current memory footprint: {}", calculateMemorySize()); } } }
private RecordResult readRecordFromStore(String cachingKey, UUIDKey key) throws JasDBStorageException { log.debug("Cache miss for record: {}", key); RecordResult result = wrappedWriter.readRecord(key); if(!result.isRecordFound()) { bucket.put(cachingKey, new CachableRecord(result)); } return result; }
private Bucket createOrGetBucket(String bucketName) throws CoreConfigException { if(!buckets.containsKey(bucketName)) { CacheConfig usedConfig = null; if(bucketConfigs.containsKey(bucketName)) { usedConfig = bucketConfigs.get(bucketName); } else { usedConfig = defaultConfig; } Bucket bucket; if(usedConfig.isEnabled()) { bucket = new CacheBucket(bucketName); } else { bucket = new DummyBucket(); } bucket.configure(usedConfig); buckets.put(bucketName, bucket); return bucket; } else { return buckets.get(bucketName); } } }
@Override public void close() throws JasDBStorageException { flush(); memoryRegion.clear(); GlobalCachingMemoryManager.getGlobalInstance().unregisterRegion(keyInfo.getKeyName()); }
@Override public void put(String key, CachableItem cacheItem) { lock.lock(); try { CacheElement element = new CacheElement(key, cacheItem); cachedItems.put(key, element); Long entryId = getEntryId(); element.setEntryId(entryId); lruItems.put(entryId, key); totalMemorySize.addAndGet(cacheItem.getObjectSize()); runInvalidator(); } finally { lock.unlock(); } }
public long calculateMemorySize() { long total = 0; for(CacheRegion<? extends Comparable, ?> region: regionMap.values()) { total += region.memorySize(); } return total; }
@Override public void removeRecord(UUIDKey documentId) throws JasDBStorageException { wrappedWriter.removeRecord(documentId); String cachingKey = storeName + "_" + documentId.toString(); bucket.remove(cachingKey); }