@Override
  public void put(K k, V v, Metadata metadata) {
    boolean l1Entry = false;
    if (metadata instanceof L1Metadata) {
      metadata = ((L1Metadata) metadata).metadata();
      l1Entry = true;
    }
    InternalCacheEntry<K, V> e = entries.get(k);

    if (trace) {
      log.tracef(
          "Creating new ICE for writing. Existing=%s, metadata=%s, new value=%s",
          e, metadata, toStr(v));
    }
    final InternalCacheEntry<K, V> copy;
    if (l1Entry) {
      copy = entryFactory.createL1(k, v, metadata);
    } else if (e != null) {
      copy = entryFactory.update(e, v, metadata);
    } else {
      // this is a brand-new entry
      copy = entryFactory.create(k, v, metadata);
    }

    if (trace) log.tracef("Store %s in container", copy);

    entries.compute(
        copy.getKey(),
        (key, entry) -> {
          activator.onUpdate(key, entry == null);
          return copy;
        });
  }
    @Override
    protected void commitSingleEntry(
        CacheEntry entry,
        Metadata metadata,
        FlagAffectedCommand command,
        InvocationContext ctx,
        Flag trackFlag,
        boolean l1Invalidation) {
      // Cache flags before they're reset
      // TODO: Can the reset be done after notification instead?
      boolean created = entry.isCreated();
      boolean removed = entry.isRemoved();
      boolean expired;
      if (removed && entry instanceof MVCCEntry) {
        expired = ((MVCCEntry) entry).isExpired();
      } else {
        expired = false;
      }

      InternalCacheEntry previousEntry = dataContainer.peek(entry.getKey());
      Object previousValue = null;
      Metadata previousMetadata = null;
      if (previousEntry != null) {
        previousValue = previousEntry.getValue();
        previousMetadata = previousEntry.getMetadata();
      }
      commitManager.commit(entry, metadata, trackFlag, l1Invalidation);

      // Notify after events if necessary
      notifyCommitEntry(
          created, removed, expired, entry, ctx, command, previousValue, previousMetadata);
    }
 private void assertContainerEntry(
     Class<? extends InternalCacheEntry> type, String expectedValue) {
   assert dc.containsKey("k");
   InternalCacheEntry entry = dc.get("k");
   assertEquals(type, entry.getClass());
   assertEquals(expectedValue, entry.getValue());
 }
  @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 void testStateTransfer() throws Exception {
    // Insert initial data in the cache
    Set<Object> keys = new HashSet<Object>();
    for (int i = 0; i < NUM_KEYS; i++) {
      Object key = "key" + i;
      keys.add(key);
      cache(0).put(key, key);
    }

    log.trace("State transfer happens here");
    // add a third node
    addClusterEnabledCacheManager(dccc);
    waitForClusterToForm();

    log.trace("Checking the values from caches...");
    int keysOnJoiner = 0;
    for (Object key : keys) {
      log.tracef("Checking key: %s", key);
      // 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);
      assertEquals(key, d0.getValue());
      assertNull(d1);
      if (d2 != null) {
        keysOnJoiner++;
      }
    }

    assertTrue("The joiner should receive at least one key", keysOnJoiner > 0);
  }
 private void testStoredEntry(
     InternalCacheEntry entry,
     Object expectedValue,
     long expectedLifespan,
     String src,
     Object key) {
   assert entry != null : src + " entry for key " + key + " should NOT be null";
   assert entry.getValue().equals(expectedValue)
       : src
           + " should contain value "
           + expectedValue
           + " under key "
           + entry.getKey()
           + " but was "
           + entry.getValue()
           + ". Entry is "
           + entry;
   assert entry.getLifespan() == expectedLifespan
       : src
           + " expected lifespan for key "
           + key
           + " to be "
           + expectedLifespan
           + " but was "
           + entry.getLifespan()
           + ". Entry is "
           + entry;
 }
 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;
 }
 @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;
 }
示例#9
0
 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();
 }
示例#10
0
 private Map<Object, Object> getPreviousValues(Set<Object> keySet) {
   HashMap<Object, Object> previousValues = new HashMap<Object, Object>();
   for (Object key : keySet) {
     InternalCacheEntry internalCacheEntry = dataContainer.get(key);
     Object previousValue = internalCacheEntry != null ? internalCacheEntry.getValue() : null;
     previousValues.put(key, previousValue);
   }
   return previousValues;
 }
示例#11
0
 public void compact() {
   for (InternalCacheEntry e : dataContainer) {
     if (e.getKey() instanceof MarshalledValue) {
       ((MarshalledValue) e.getKey()).compact(true, true);
     }
     if (e.getValue() instanceof MarshalledValue) {
       ((MarshalledValue) e.getValue()).compact(true, true);
     }
   }
 }
 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();
     }
   }
 }
 private Object remoteGet(InvocationContext ctx, Object key, GetKeyValueCommand command)
     throws Throwable {
   if (trace) log.tracef("Doing a remote get for key %s", key);
   InternalCacheEntry ice = dm.retrieveFromRemoteSource(key, ctx, false, command);
   command.setRemotelyFetchedValue(ice);
   if (ice != null) {
     return ice.getValue();
   }
   return null;
 }
示例#14
0
  @Override
  public void notifyCacheEntriesEvicted(
      Collection<InternalCacheEntry<? extends K, ? extends V>> entries,
      InvocationContext ctx,
      FlagAffectedCommand command) {
    if (!entries.isEmpty()) {
      if (isNotificationAllowed(command, cacheEntriesEvictedListeners)) {
        EventImpl<K, V> e = EventImpl.createEvent(cache, CACHE_ENTRY_EVICTED);
        Map<K, V> evictedKeysAndValues =
            transformCollectionToMap(
                entries,
                new InfinispanCollections.MapMakerFunction<
                    K, V, InternalCacheEntry<? extends K, ? extends V>>() {
                  @Override
                  public Map.Entry<K, V> transform(
                      final InternalCacheEntry<? extends K, ? extends V> input) {
                    return new Map.Entry<K, V>() {
                      @Override
                      public K getKey() {
                        return input.getKey();
                      }

                      @Override
                      public V getValue() {
                        return input.getValue();
                      }

                      @Override
                      public V setValue(V value) {
                        throw new UnsupportedOperationException();
                      }
                    };
                  }
                });

        e.setEntries(evictedKeysAndValues);
        for (CacheEntryListenerInvocation<K, V> listener : cacheEntriesEvictedListeners)
          listener.invoke(e);
      }

      // For backward compat
      if (isNotificationAllowed(command, cacheEntryEvictedListeners)) {
        for (InternalCacheEntry<? extends K, ? extends V> ice : entries) {
          EventImpl<K, V> e = EventImpl.createEvent(cache, CACHE_ENTRY_EVICTED);
          e.setKey(ice.getKey());
          e.setValue(ice.getValue());
          boolean isLocalNodePrimaryOwner =
              clusteringDependentLogic.localNodeIsPrimaryOwner(ice.getKey());
          for (CacheEntryListenerInvocation<K, V> listener : cacheEntryEvictedListeners)
            listener.invoke(e, isLocalNodePrimaryOwner);
        }
      }
    }
  }
 private void commitClearCommand(
     DataContainer<Object, Object> dataContainer,
     ClearCacheEntry<Object, Object> cacheEntry,
     InvocationContext context,
     FlagAffectedCommand command) {
   List<InternalCacheEntry<Object, Object>> copyEntries =
       new ArrayList<>(dataContainer.entrySet());
   cacheEntry.commit(dataContainer, null);
   for (InternalCacheEntry entry : copyEntries) {
     notifier.notifyCacheEntryRemoved(
         entry.getKey(), entry.getValue(), entry.getMetadata(), false, context, command);
   }
 }
 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;
 }
示例#17
0
 private MVCCEntry wrapInternalCacheEntryForPut(
     InvocationContext ctx, Object key, InternalCacheEntry cacheEntry) {
   MVCCEntry mvccEntry =
       createWrappedEntry(
           key,
           cacheEntry.getValue(),
           cacheEntry.getVersion(),
           false,
           false,
           cacheEntry.getLifespan());
   ctx.putLookedUpEntry(key, mvccEntry);
   return mvccEntry;
 }
示例#18
0
 private MVCCEntry wrapEntry(InvocationContext ctx, Object key) {
   CacheEntry cacheEntry = getFromContext(ctx, key);
   MVCCEntry mvccEntry = null;
   if (cacheEntry != null) {
     mvccEntry = wrapMvccEntryForPut(ctx, key, cacheEntry);
   } else {
     InternalCacheEntry ice = getFromContainer(key);
     if (ice != null) {
       mvccEntry = wrapInternalCacheEntryForPut(ctx, ice.getKey(), ice);
     }
   }
   if (mvccEntry != null) mvccEntry.copyForUpdate(container, localModeWriteSkewCheck);
   return mvccEntry;
 }
  public void testExpiredData() throws InterruptedException {
    dc.put("k", "v", -1, 6000000);
    Thread.sleep(100);

    InternalCacheEntry entry = dc.get("k");
    assert entry.getClass().equals(transienttype());
    assert entry.getLastUsed() <= System.currentTimeMillis();
    long entryLastUsed = entry.getLastUsed();
    Thread.sleep(100);
    entry = dc.get("k");
    assert entry.getLastUsed() > entryLastUsed;
    dc.put("k", "v", -1, 0);
    dc.purgeExpired();

    dc.put("k", "v", 6000000, -1);
    Thread.sleep(100);
    assert dc.size() == 1;

    entry = dc.get("k");
    assert entry != null : "Entry should not be null!";
    assert entry.getClass().equals(mortaltype())
        : "Expected " + mortaltype() + ", was " + entry.getClass().getSimpleName();
    assert entry.getCreated() <= System.currentTimeMillis();

    dc.put("k", "v", 0, -1);
    Thread.sleep(10);
    assert dc.get("k") == null;
    assert dc.size() == 0;

    dc.put("k", "v", 0, -1);
    Thread.sleep(100);
    assert dc.size() == 1;
    dc.purgeExpired();
    assert dc.size() == 0;
  }
示例#20
0
 @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;
 }
  public void testEvictBeforeRead()
      throws CacheLoaderException, ExecutionException, InterruptedException {
    cache = cacheManager.getCache();
    cache.put("a", "b");
    assert cache.get("a").equals("b");
    CacheLoader cl = TestingUtil.getCacheLoader(cache);
    assert cl != null;
    InternalCacheEntry se = cl.load("a");
    assert se != null;
    assert se.getValue().equals("b");

    // clear the cache
    cache.getAdvancedCache().withFlags(SKIP_CACHE_STORE).clear();

    se = cl.load("a");
    assert se != null;
    assert se.getValue().equals("b");

    // now attempt a concurrent get and evict.
    ExecutorService e = Executors.newFixedThreadPool(1);
    sdi.enabled = true;

    log.info("test::doing the get");

    // call the get
    Future<String> future =
        e.submit(
            new Callable<String>() {
              public String call() throws Exception {
                return (String) cache.get("a");
              }
            });

    // now run the evict.
    log.info("test::before the evict");
    cache.evict("a");
    log.info("test::after the evict");

    // make sure the get call, which would have gone past the cache loader interceptor first, gets
    // the correct value.
    assert future.get().equals("b");

    // disable the SlowDownInterceptor
    sdi.enabled = false;

    // and check that the key actually has been evicted
    assert !TestingUtil.extractComponent(cache, DataContainer.class).containsKey("a");

    e.shutdownNow();
  }
    @Override
    public boolean contains(Object o) {
      if (!(o instanceof Map.Entry)) {
        return false;
      }

      @SuppressWarnings("rawtypes")
      Map.Entry e = (Map.Entry) o;
      InternalCacheEntry ice = entries.get(e.getKey());
      if (ice == null) {
        return false;
      }
      return ice.getValue().equals(e.getValue());
    }
示例#23
0
 @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;
 }
示例#24
0
 @Override
 public CacheEntry wrapEntryForDelta(InvocationContext ctx, Object deltaKey, Delta delta)
     throws InterruptedException {
   CacheEntry cacheEntry = getFromContext(ctx, deltaKey);
   DeltaAwareCacheEntry deltaAwareEntry = null;
   if (cacheEntry != null) {
     deltaAwareEntry = wrapEntryForDelta(ctx, deltaKey, cacheEntry);
   } else {
     InternalCacheEntry ice = getFromContainer(deltaKey);
     if (ice != null) {
       deltaAwareEntry = newDeltaAwareCacheEntry(ctx, deltaKey, (DeltaAware) ice.getValue());
     }
   }
   if (deltaAwareEntry != null) deltaAwareEntry.appendDelta(delta);
   return deltaAwareEntry;
 }
示例#25
0
 public Object getValueAt(int rowIndex, int columnIndex) {
   if (data.size() > rowIndex) {
     InternalCacheEntry e = data.get(rowIndex);
     switch (columnIndex) {
       case 0:
         return e.getKey();
       case 1:
         return e.getValue();
       case 2:
         return e.getLifespan();
       case 3:
         return e.getMaxIdle();
     }
   }
   return "NULL!";
 }
示例#26
0
  @Override
  public void notifyCacheEntriesEvicted(
      Collection<InternalCacheEntry> entries, InvocationContext ctx, FlagAffectedCommand command) {
    if (!entries.isEmpty()) {
      if (isNotificationAllowed(command, cacheEntriesEvictedListeners)) {
        EventImpl<Object, Object> e = EventImpl.createEvent(cache, CACHE_ENTRY_EVICTED);
        Map<Object, Object> evictedKeysAndValues =
            transformCollectionToMap(
                entries,
                new InfinispanCollections.MapMakerFunction<Object, Object, InternalCacheEntry>() {
                  @Override
                  public Map.Entry<Object, Object> transform(final InternalCacheEntry input) {
                    return new Map.Entry<Object, Object>() {
                      @Override
                      public Object getKey() {
                        return input.getKey();
                      }

                      @Override
                      public Object getValue() {
                        return input.getValue();
                      }

                      @Override
                      public Object setValue(Object value) {
                        throw new UnsupportedOperationException();
                      }
                    };
                  }
                });

        e.setEntries(evictedKeysAndValues);
        for (ListenerInvocation listener : cacheEntriesEvictedListeners) listener.invoke(e);
      }

      // For backward compat
      if (isNotificationAllowed(command, cacheEntryEvictedListeners)) {
        for (InternalCacheEntry ice : entries) {
          EventImpl<Object, Object> e = EventImpl.createEvent(cache, CACHE_ENTRY_EVICTED);
          e.setKey(ice.getKey());
          e.setValue(ice.getValue());
          for (ListenerInvocation listener : cacheEntryEvictedListeners) listener.invoke(e);
        }
      }
    }
  }
 private Object getValue(Object key) {
   log.tracef("Checking key: %s", key);
   InternalCacheEntry d0 = advancedCache(0).getDataContainer().get(key);
   InternalCacheEntry d1 = advancedCache(1).getDataContainer().get(key);
   InternalCacheEntry d2 = advancedCache(2).getDataContainer().get(key);
   if (d0 == null) {
     assert sameValue(d1, d2);
     return d1.getValue();
   } else if (d1 == null) {
     assert sameValue(d0, d2);
     return d0.getValue();
   } else if (d2 == null) {
     assert sameValue(d0, d1);
     return d0.getValue();
   }
   throw new RuntimeException();
 }
 public void put(Object k, Object v, EntryVersion version, long lifespan, long maxIdle) {
   InternalCacheEntry e = entries.get(k);
   if (e != null) {
     e.setValue(v);
     InternalCacheEntry original = e;
     e.setVersion(version);
     e = entryFactory.update(e, lifespan, maxIdle);
     // we have the same instance. So we need to reincarnate.
     if (original == e) {
       e.reincarnate();
     }
   } else {
     // this is a brand-new entry
     e = entryFactory.create(k, v, version, lifespan, maxIdle);
   }
   entries.put(k, e);
 }
  public void testContainerIteration() {
    dc.put("k1", "v", 6000000, -1);
    dc.put("k2", "v", -1, -1);
    dc.put("k3", "v", -1, 6000000);
    dc.put("k4", "v", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add("k1");
    expected.add("k2");
    expected.add("k3");
    expected.add("k4");

    for (InternalCacheEntry ice : dc) {
      assert expected.remove(ice.getKey());
    }

    assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
  }
  public void testGetsFromMultipleSrcs() throws Exception {

    assert cs.load("k1") == null;
    assert cs.load("k2") == null;
    assert cs.load("k3") == null;
    assert cs.load("k4") == null;

    // k1 is on store1
    store1.store(InternalEntryFactory.create("k1", "v1"));

    assertEquals(cs.loadAll().size(), 1);
    // k2 is on store2
    store2.store(InternalEntryFactory.create("k2", "v2"));
    assertEquals(cs.loadAll().size(), 2);

    // k3 is on both
    store1.store(InternalEntryFactory.create("k3", "v3"));
    assertEquals(cs.loadAll().size(), 3);
    store2.store(InternalEntryFactory.create("k3", "v3"));
    assertEquals(cs.loadAll().size(), 3);

    // k4 is on neither

    assert cs.load("k1").getValue().equals("v1");
    assert cs.load("k2").getValue().equals("v2");
    assert cs.load("k3").getValue().equals("v3");
    assert cs.load("k4") == null;

    Set<InternalCacheEntry> all = cs.loadAll();

    assertEquals(all.size(), 3);
    Set<Object> expectedKeys = new HashSet<Object>();
    expectedKeys.add("k1");
    expectedKeys.add("k2");
    expectedKeys.add("k3");
    for (InternalCacheEntry a : all) assert expectedKeys.remove(a.getKey());

    assert expectedKeys.isEmpty();

    cs.remove("k3");

    assert !store1.containsKey("k3");
    assert !store2.containsKey("k3");
  }