@Override protected String toString(InternalCacheEntry ice) { if (ice == null) return null; StringBuilder sb = new StringBuilder(256); sb.append(ice.getClass().getSimpleName()); sb.append("[key=").append(ice.getKey()).append(", value=").append(ice.getValue()); sb.append(", created=").append(ice.getCreated()).append(", isCreated=").append(ice.isCreated()); sb.append(", lastUsed=") .append(ice.getLastUsed()) .append(", isChanged=") .append(ice.isChanged()); sb.append(", expires=") .append(ice.getExpiryTime()) .append(", isExpired=") .append(ice.isExpired(System.currentTimeMillis())); sb.append(", canExpire=") .append(ice.canExpire()) .append(", isEvicted=") .append(ice.isEvicted()); sb.append(", isRemoved=").append(ice.isRemoved()).append(", isValid=").append(ice.isValid()); sb.append(", lifespan=") .append(ice.getLifespan()) .append(", maxIdle=") .append(ice.getMaxIdle()); return sb.append(']').toString(); }
@Override public final void store(InternalCacheEntry ed) throws CacheLoaderException { if (trace) { log.tracef("store(%s)", ed); } if (ed == null) { return; } if (ed.canExpire() && ed.isExpired(System.currentTimeMillis())) { if (containsKey(ed.getKey())) { if (trace) { log.tracef("Entry %s is expired! Removing!", ed); } remove(ed.getKey()); } else { if (trace) { log.tracef("Entry %s is expired! Not doing anything.", ed); } } return; } L keyHashCode = getLockFromKey(ed.getKey()); lockForWriting(keyHashCode); try { storeLockSafe(ed, keyHashCode); } finally { unlock(keyHashCode); } if (trace) { log.tracef("exit store(%s)", ed); } }
public boolean containsKey(Object k) { InternalCacheEntry ice = peek(k); if (ice != null && ice.canExpire() && ice.isExpired(System.currentTimeMillis())) { entries.remove(k); ice = null; } return ice != null; }
public void testIdleExpiryInPut() throws InterruptedException { Cache<String, String> cache = cm.getCache(); long idleTime = IDLE_TIMEOUT; cache.put("k", "v", -1, MILLISECONDS, idleTime, MILLISECONDS); DataContainer dc = cache.getAdvancedCache().getDataContainer(); InternalCacheEntry se = dc.get("k", null); assert se.getKey().equals("k"); assert se.getValue().equals("v"); assert se.getLifespan() == -1; assert se.getMaxIdle() == idleTime; assert !se.isExpired(); assert cache.get("k").equals("v"); Thread.sleep(idleTime + 100); assert se.isExpired(); assert cache.get("k") == null; }
public void update() { // whew - expensive stuff. data.clear(); for (InternalCacheEntry ice : cache.getAdvancedCache().getDataContainer()) { if (!ice.isExpired()) data.add(ice); } cacheContentsSizeLabel.setText("Cache contains " + data.size() + " entries"); fireTableDataChanged(); }
@Override public boolean containsKey(Object k) { InternalCacheEntry<K, V> ice = peek(k); if (ice != null && ice.canExpire() && ice.isExpired(timeService.wallClockTime())) { entries.remove(k); ice = null; } return ice != null; }
public void purgeExpired() { long currentTimeMillis = System.currentTimeMillis(); for (Iterator<InternalCacheEntry> purgeCandidates = entries.values().iterator(); purgeCandidates.hasNext(); ) { InternalCacheEntry e = purgeCandidates.next(); if (e.isExpired(currentTimeMillis)) { purgeCandidates.remove(); } } }
public InternalCacheEntry get(Object k) { InternalCacheEntry e = peek(k); if (e != null && e.canExpire()) { long currentTimeMillis = System.currentTimeMillis(); if (e.isExpired(currentTimeMillis)) { entries.remove(k); e = null; } else { e.touch(currentTimeMillis); } } return e; }
@Override public InternalCacheEntry<K, V> get(Object k) { InternalCacheEntry<K, V> e = entries.get(k); if (e != null && e.canExpire()) { long currentTimeMillis = timeService.wallClockTime(); if (e.isExpired(currentTimeMillis)) { expirationManager.handleInMemoryExpiration(e, currentTimeMillis); e = null; } else { e.touch(currentTimeMillis); } } return e; }
@Override public InternalCacheEntry<K, V> remove(Object k) { final InternalCacheEntry<K, V>[] reference = new InternalCacheEntry[1]; entries.compute( (K) k, (key, entry) -> { activator.onRemove(key, entry == null); reference[0] = entry; return null; }); InternalCacheEntry<K, V> e = reference[0]; if (trace) { log.tracef("Removed %s from container", e); } return e == null || (e.canExpire() && e.isExpired(timeService.wallClockTime())) ? null : e; }
private InternalCacheEntry<K, V> getNext() { boolean initializedTime = false; long now = 0; while (it.hasNext()) { InternalCacheEntry<K, V> entry = it.next(); if (includeExpired || !entry.canExpire()) { return entry; } else { if (!initializedTime) { now = timeService.wallClockTime(); initializedTime = true; } if (!entry.isExpired(now)) { return entry; } } } return null; }
@Override public InternalCacheEntry load(Object key) throws CacheLoaderException { String hashKey = hashKey(key); Cassandra.Client cassandraClient = null; try { cassandraClient = dataSource.getConnection(); ColumnOrSuperColumn column = cassandraClient.get(ByteBufferUtil.bytes(hashKey), entryColumnPath, readConsistencyLevel); InternalCacheEntry ice = unmarshall(column.getColumn().getValue(), key); if (ice != null && ice.isExpired()) { remove(key); return null; } return ice; } catch (NotFoundException nfe) { log.debugf("Key '%s' not found", hashKey); return null; } catch (Exception e) { throw new CacheLoaderException(e); } finally { dataSource.releaseConnection(cassandraClient); } }
private void testLockMigration(int nodeThatPuts, boolean commit) throws Exception { Map<Object, Transaction> key2Tx = new HashMap<Object, Transaction>(); for (int i = 0; i < NUM_KEYS; i++) { Object key = getKeyForCache(0); if (key2Tx.containsKey(key)) continue; // put a key to have some data in cache cache(nodeThatPuts).put(key, key); // start a TX that locks the key and then we suspend it tm(nodeThatPuts).begin(); Transaction tx = tm(nodeThatPuts).getTransaction(); advancedCache(nodeThatPuts).lock(key); tm(nodeThatPuts).suspend(); key2Tx.put(key, tx); assertLocked(0, key); } log.trace("Lock transfer happens here"); // add a third node hoping that some of the previously created keys will be migrated to it addClusterEnabledCacheManager(dccc); waitForClusterToForm(); // search for a key that was migrated to third node and the suspended TX that locked it Object migratedKey = null; Transaction migratedTransaction = null; ConsistentHash consistentHash = advancedCache(2).getDistributionManager().getConsistentHash(); for (Object key : key2Tx.keySet()) { if (consistentHash.locatePrimaryOwner(key).equals(address(2))) { migratedKey = key; migratedTransaction = key2Tx.get(key); log.trace("Migrated key = " + migratedKey); log.trace( "Migrated transaction = " + ((DummyTransaction) migratedTransaction).getEnlistedResources()); break; } } // we do not focus on the other transactions so we commit them now log.trace("Committing all transactions except the migrated one."); for (Object key : key2Tx.keySet()) { if (!key.equals(migratedKey)) { Transaction tx = key2Tx.get(key); tm(nodeThatPuts).resume(tx); tm(nodeThatPuts).commit(); } } if (migratedKey == null) { // this could happen in extreme cases log.trace("No key migrated to new owner - test cannot be performed!"); } else { // the migrated TX is resumed and committed or rolled back. we expect the migrated key to be // unlocked now tm(nodeThatPuts).resume(migratedTransaction); if (commit) { tm(nodeThatPuts).commit(); } else { tm(nodeThatPuts).rollback(); } // there should not be any locks assertNotLocked(cache(0), migratedKey); assertNotLocked(cache(1), migratedKey); assertNotLocked(cache(2), migratedKey); // if a new TX tries to write to the migrated key this should not fail, the key should not be // locked tm(nodeThatPuts).begin(); cache(nodeThatPuts) .put( migratedKey, "someValue"); // this should not result in TimeoutException due to key still locked tm(nodeThatPuts).commit(); } log.trace("Checking the values from caches..."); for (Object key : key2Tx.keySet()) { log.tracef("Checking key: %s", key); Object expectedValue = key; if (key.equals(migratedKey)) { expectedValue = "someValue"; } // check them directly in data container InternalCacheEntry d0 = advancedCache(0).getDataContainer().get(key); InternalCacheEntry d1 = advancedCache(1).getDataContainer().get(key); InternalCacheEntry d2 = advancedCache(2).getDataContainer().get(key); int c = 0; if (d0 != null && !d0.isExpired(TIME_SERVICE.wallClockTime())) { assertEquals(expectedValue, d0.getValue()); c++; } if (d1 != null && !d1.isExpired(TIME_SERVICE.wallClockTime())) { assertEquals(expectedValue, d1.getValue()); c++; } if (d2 != null && !d2.isExpired(TIME_SERVICE.wallClockTime())) { assertEquals(expectedValue, d2.getValue()); c++; } assertEquals(1, c); // look at them also via cache API assertEquals(expectedValue, cache(0).get(key)); assertEquals(expectedValue, cache(1).get(key)); assertEquals(expectedValue, cache(2).get(key)); } }
@Override public InternalCacheEntry remove(Object k) { InternalCacheEntry e = entries.remove(k); return e == null || (e.canExpire() && e.isExpired(System.currentTimeMillis())) ? null : e; }