diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java index 90012c72bdaf2..d288333646cbd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryInfo.java @@ -19,24 +19,24 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.SelfMarshallingMessage; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.plugin.extensions.communication.CacheIdAware; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; /** * Entry information that gets passed over wire. */ -public class GridCacheEntryInfo implements SelfMarshallingMessage, CacheIdAware { +public class GridCacheEntryInfo implements CacheIdAware, Message { /** */ private static final int SIZE_OVERHEAD = 3 * 8 /* reference */ + 4 /* int */ + 2 * 8 /* long */ + 32 /* version */; /** Cache key. */ @Order(0) @GridToStringInclude - KeyCacheObject key; + @Nullable KeyCacheObject key; /** Cache ID. */ @Order(1) @@ -44,15 +44,23 @@ public class GridCacheEntryInfo implements SelfMarshallingMessage, CacheIdAware /** Cache value. */ @Order(2) - CacheObject val; + @Nullable CacheObject val; /** Time to live. */ @Order(3) long ttl; - /** Expiration time. */ + /** Base time to calculate {@link #expireTime()}. 0 if no expiration is used. */ + long initTime; + + /** + * Expiration time delta to transfer. {@link Long#MIN_VALUE} means no expiration enabled. In theory, we can get + * the calculating time delta thread paused causing a negative delta value. This shouldn't be treated as disabled + * expiration. Correct behavior is expired timeout. {@link Long#MIN_VALUE} is taken as one with unrealistic chance + * to appear. + */ @Order(4) - long expireTime; + long expireTimeDelta = Long.MIN_VALUE; /** Entry version. */ @Order(5) @@ -64,58 +72,66 @@ public class GridCacheEntryInfo implements SelfMarshallingMessage, CacheIdAware /** Deleted flag. */ private boolean deleted; - /** {@inheritDoc} */ - @Override public int cacheId() { - return cacheId; - } - /** - * @param cacheId Cache ID. + * Empty constructor for serialization purposes. + * see {@link #expireTimeDelta}. */ - public void cacheId(int cacheId) { + public GridCacheEntryInfo() { + initTime = System.currentTimeMillis(); + } + + /** */ + public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long expireTime, long ttl) { + assert expireTime >= 0; + + if (expireTime != 0) { + // In theory, here we can get the thread paused causing a negative delta value. Possible negative values + // shouldn't be treated as disabled expiration. Correct behavior is expired timeout. + initTime = System.currentTimeMillis(); + + expireTimeDelta = expireTime - initTime; + } + this.cacheId = cacheId; + this.key = key; + this.val = val; + this.ver = ver; + this.ttl = ttl; + } + + /** {@inheritDoc} */ + @Override public int cacheId() { + return cacheId; } /** * @param key Entry key. */ - public void key(KeyCacheObject key) { + public void key(@Nullable KeyCacheObject key) { this.key = key; } /** * @return Entry key. */ - public KeyCacheObject key() { + @Nullable public KeyCacheObject key() { return key; } /** * @return Entry value. */ - public CacheObject value() { + public @Nullable CacheObject value() { return val; } /** - * @param val Entry value. - */ - public void value(CacheObject val) { - this.val = val; - } - - /** - * @return Expire time. + * @return Expire time >= 0. 0 means no expiration is set. */ public long expireTime() { - return expireTime; - } + assert initTime >= 0; - /** - * @param expireTime Expiration time. - */ - public void expireTime(long expireTime) { - this.expireTime = expireTime; + return expireTimeDelta == Long.MIN_VALUE ? 0L : initTime + expireTimeDelta; } /** @@ -125,13 +141,6 @@ public long ttl() { return ttl; } - /** - * @param ttl Time to live. - */ - public void ttl(long ttl) { - this.ttl = ttl; - } - /** * @return Version. */ @@ -139,13 +148,6 @@ public GridCacheVersion version() { return ver; } - /** - * @param ver Version. - */ - public void version(GridCacheVersion ver) { - this.ver = ver; - } - /** * @return New flag. */ @@ -190,30 +192,6 @@ public int marshalledSize(CacheObjectContext ctx) throws IgniteCheckedException return SIZE_OVERHEAD + size; } - // TODO IGNITE-28920: the rebase still runs inside the message; move it to the code filling and reading the entry. - /** {@inheritDoc} */ - @Override public void selfMarshal() { - if (expireTime == 0) - expireTime = -1; - else { - expireTime -= U.currentTimeMillis(); - - if (expireTime < 0) - expireTime = 0; - } - } - - /** {@inheritDoc} */ - @Override public void selfUnmarshal() { - long remaining = expireTime; - - expireTime = remaining < 0 ? 0 : U.currentTimeMillis() + remaining; - - // Account for overflow. - if (expireTime < 0) - expireTime = 0; - } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridCacheEntryInfo.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java index e50b225d1ef93..355dd51ce89b8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java @@ -396,23 +396,14 @@ protected GridDhtLocalPartition localPartition() { try { if (!obsolete()) { - info = new GridCacheEntryInfo(); - - info.key(key); - info.cacheId(cctx.cacheId()); - long expireTime = expireTimeExtras(); - boolean expired = expireTime != 0 && expireTime <= U.currentTimeMillis(); + CacheObject val0 = expireTime == 0 || expireTime > U.currentTimeMillis() ? val : null; + + info = new GridCacheEntryInfo(cctx.cacheId(), key, val0, ver, expireTime, ttlExtras()); - info.ttl(ttlExtras()); - info.expireTime(expireTime); - info.version(ver); info.setNew(isStartVersion()); info.setDeleted(deletedUnlocked()); - - if (!expired) - info.value(val); } } finally { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java index 5a7585353156f..19898f60e29c1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java @@ -29,7 +29,6 @@ import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; -import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.EntryGetResult; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo; @@ -502,14 +501,14 @@ private Collection toEntryInfos(Map map) assert val != null; - GridCacheEntryInfo info = new GridCacheEntryInfo(); - - info.cacheId(cctx.cacheId()); - info.key(key); - info.value(skipVals ? null : (CacheObject)val.value()); - info.version(val.version()); - info.expireTime(val.expireTime()); - info.ttl(val.ttl()); - - return info; + return new GridCacheEntryInfo( + cctx.cacheId(), + key, + skipVals ? null : val.value(), + val.version(), + val.expireTime(), + val.ttl() + ); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java index 2515730634396..f49231715db4b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java @@ -349,13 +349,7 @@ public void handleDemandMessage(int topicId, UUID nodeId, GridDhtPartitionDemand if (!remainingParts.contains(part)) continue; - GridCacheEntryInfo info = new GridCacheEntryInfo(); - - info.key(row.key()); - info.cacheId(row.cacheId()); - info.value(row.value()); - info.version(row.version()); - info.expireTime(row.expireTime()); + GridCacheEntryInfo info = new GridCacheEntryInfo(row.cacheId(), row.key(), row.value(), row.version(), row.expireTime(), 0); supplyMsg.addEntry0(part, iter.historical(part), info, grp.shared(), grp.cacheObjectContext()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java index 640cd98a8aaab..c3e3f79d7d7cb 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java @@ -269,15 +269,7 @@ void recheckLock() { /** {@inheritDoc} */ @Override public GridCacheEntryInfo info() { - GridCacheEntryInfo info = new GridCacheEntryInfo(); - - info.key(key()); - info.value(val); - info.ttl(ttl()); - info.expireTime(expireTime()); - info.version(version()); - - return info; + return new GridCacheEntryInfo(0, key(), val, version(), expireTime(), ttl()); } /** {@inheritDoc} */