@Override public Void apply(EntryView.ReadWriteEntryView<Object, Object> view) { Object storedValue = view.find().orElse(null); if (value == null) { if (storedValue != null && !(storedValue instanceof Tombstone)) { // We have to keep Tombstone, because otherwise putFromLoad could insert a stale entry // (after it has been already updated and *then* evicted) view.set(new Tombstone(ZERO, timestamp), region.getExpiringMetaParam()); } // otherwise it's eviction } else if (storedValue instanceof Tombstone) { Tombstone tombstone = (Tombstone) storedValue; if (tombstone.getLastTimestamp() < timestamp) { view.set(value); } } else if (storedValue == null) { // async putFromLoads shouldn't cross the invalidation timestamp if (region.getLastRegionInvalidation() < timestamp) { view.set(value); } } else { // Don't do anything locally. This could be the async remote write, though, when local // value has been already updated: let it propagate to remote nodes, too view.set(storedValue, view.findMetaParam(MetaParam.MetaLifespan.class).get()); } return null; }
@Override protected Object perform(TestWriteOperation op, AdvancedCache<Object, Object> cache0, String key) { try { return super.perform(op, cache0, key); } catch (IllegalArgumentException e) { switch (op) { case REPLACE_META_FUNCTIONAL: return FunctionalTestUtils.await(rw(cache0).eval(key, "v1", (v, rw) -> { return rw.findMetaParam(MetaEntryVersion.class) .filter(ver -> ver.get().compareTo(new NumericVersion(1)) == EQUAL) .map(ver -> { rw.set(v, new MetaEntryVersion(new NumericVersion(2))); return true; }).orElse(false); })); default: throw new AssertionError("Unknown operation: " + op); } } }
/** * Read-write allows for replace operations to happen based on version * comparison, and update version information if replace is versions are * equals. * * This is the kind of advance operation that Hot Rod prototocol requires * but the current Infinispan API is unable to offer without offering * atomicity at the level of the function that compares the version * information. */ <K> void doReadWriteForConditionalParamBasedReplace(Supplier<K> keySupplier, ReadWriteMap<K, String> map1, ReadWriteMap<K, String> map2) { replaceWithVersion(keySupplier, map1, map2, 100, rw -> { assertEquals("uno", rw.get()); assertEquals(Optional.of(new MetaEntryVersion(new NumericVersion(200))), rw.findMetaParam(MetaEntryVersion.class)); } ); replaceWithVersion(keySupplier, map1, map2, 900, rw -> { assertEquals(Optional.of("one"), rw.find()); assertEquals(Optional.of(new MetaEntryVersion(new NumericVersion(100))), rw.findMetaParam(MetaEntryVersion.class)); }); }
@Override public ReadWriteEntryView<K, String> apply(ReadWriteEntryView<K, String> rw) { Optional<MetaEntryVersion> metaParam = rw.findMetaParam(MetaEntryVersion.class); metaParam.ifPresent(metaVersion -> { if (metaVersion.get().compareTo(new NumericVersion(version)) == EQUAL) rw.set("uno", new MetaEntryVersion(new NumericVersion(200))); }); return rw; }