From 6a79f1173b368fe022e7f28229037b338df5436f Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Fri, 7 Aug 2026 13:26:28 +0300 Subject: [PATCH 01/15] impl --- .../processors/cache/GridCacheEntryInfo.java | 41 +++++-------------- .../distributed/dht/GridDhtGetFuture.java | 3 +- 2 files changed, 11 insertions(+), 33 deletions(-) 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..cb13ed92325fd 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,17 +19,16 @@ 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; /** * Entry information that gets passed over wire. */ -public class GridCacheEntryInfo implements SelfMarshallingMessage, CacheIdAware { +public class GridCacheEntryInfo implements Message, CacheIdAware { /** */ private static final int SIZE_OVERHEAD = 3 * 8 /* reference */ + 4 /* int */ + 2 * 8 /* long */ + 32 /* version */; @@ -50,9 +49,9 @@ public class GridCacheEntryInfo implements SelfMarshallingMessage, CacheIdAware @Order(3) long ttl; - /** Expiration time. */ + /** Expiration time delta. */ @Order(4) - long expireTime; + long expireTimeLeft; /** Entry version. */ @Order(5) @@ -108,14 +107,18 @@ public void value(CacheObject val) { * @return Expire time. */ public long expireTime() { - return expireTime; + /** {@link Long#MIN_VALUE} means the expiration wasn't used. */ + return expireTimeLeft == Long.MIN_VALUE ? 0 : System.currentTimeMillis() + expireTimeLeft; } /** + * Converts absolute exipation time to time-left/delta. Supposes that 0 means to expiration used. + * * @param expireTime Expiration time. */ public void expireTime(long expireTime) { - this.expireTime = expireTime; + /** {@link Long#MIN_VALUE} means the expiration isn't used. */ + expireTimeLeft = expireTime == 0 ? Long.MIN_VALUE : expireTime - System.currentTimeMillis(); } /** @@ -190,30 +193,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/distributed/dht/GridDhtGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java index 5a7585353156f..62651af06062d 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; @@ -506,7 +505,7 @@ private Collection toEntryInfos(Map Date: Fri, 7 Aug 2026 13:26:28 +0300 Subject: [PATCH 02/15] impl --- .../processors/cache/GridCacheEntryInfo.java | 105 ++++++------------ .../processors/cache/GridCacheMapEntry.java | 15 +-- .../distributed/dht/GridDhtGetFuture.java | 17 ++- .../dht/GridDhtGetSingleFuture.java | 17 ++- .../preloader/GridDhtPartitionSupplier.java | 8 +- .../cache/GridCacheTestEntryEx.java | 10 +- 6 files changed, 56 insertions(+), 116 deletions(-) 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..c246c930fb6d6 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,18 @@ 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()}. */ + long initTime; + + /** Expiration time delta to transfer. {@link Long#MIN_VALUE} means no expiration is set. */ @Order(4) - long expireTime; + long expireTimeTransferDelta = Long.MIN_VALUE; /** Entry version. */ @Order(5) @@ -64,58 +67,58 @@ public class GridCacheEntryInfo implements SelfMarshallingMessage, CacheIdAware /** Deleted flag. */ private boolean deleted; - /** {@inheritDoc} */ - @Override public int cacheId() { - return cacheId; + /** Empty constructor for serialization purposes. Sets {@link #initTime}. */ + public GridCacheEntryInfo() { + initTime = System.currentTimeMillis(); } - /** - * @param cacheId Cache ID. - */ - public void cacheId(int cacheId) { + /** */ + public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long ttl, long expireTime) { + if (expireTime == 0) { + /** {@link Long#MIN_VALUE} means no expiration is set. */ + expireTimeTransferDelta = Long.MIN_VALUE; + } + else + expireTimeTransferDelta = expireTime == 0 ? Long.MIN_VALUE : 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. */ public long expireTime() { - return expireTime; - } - - /** - * @param expireTime Expiration time. - */ - public void expireTime(long expireTime) { - this.expireTime = expireTime; + return expireTimeTransferDelta == Long.MIN_VALUE ? 0 : initTime + expireTimeTransferDelta; } /** @@ -125,13 +128,6 @@ public long ttl() { return ttl; } - /** - * @param ttl Time to live. - */ - public void ttl(long ttl) { - this.ttl = ttl; - } - /** * @return Version. */ @@ -139,13 +135,6 @@ public GridCacheVersion version() { return ver; } - /** - * @param ver Version. - */ - public void version(GridCacheVersion ver) { - this.ver = ver; - } - /** * @return New flag. */ @@ -190,30 +179,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..09118e3aa9402 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, ttlExtras(), expireTime); - 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..7ca0776107230 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()); + GridCacheEntryInfo info = new GridCacheEntryInfo( + cctx.cacheId(), + key, + skipVals ? null : val.value(), + val.version(), + val.ttl(), + val.expireTime() + ); return info; } 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..5fde5ed2440a3 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(), 0, row.expireTime()); 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..86fcd4be96167 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(), ttl(), expireTime()); } /** {@inheritDoc} */ From efd5744904c47bc8dd594925a3caa4d237792556 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Fri, 7 Aug 2026 14:27:00 +0300 Subject: [PATCH 03/15] minority --- .../ignite/internal/processors/cache/GridCacheEntryInfo.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 c246c930fb6d6..7a2fb892c8863 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 @@ -67,7 +67,10 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { /** Deleted flag. */ private boolean deleted; - /** Empty constructor for serialization purposes. Sets {@link #initTime}. */ + /** + * Empty constructor for serialization purposes. + * see {@link #expireTimeTransferDelta}. + */ public GridCacheEntryInfo() { initTime = System.currentTimeMillis(); } From 3b944de29af15ffcbe04b3f7b78d0fc2156643ad Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Fri, 7 Aug 2026 20:27:28 +0300 Subject: [PATCH 04/15] try fix --- .../ignite/internal/processors/cache/GridCacheEntryInfo.java | 5 ++++- .../processors/cache/ttl/CacheTtlAbstractSelfTest.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) 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 7a2fb892c8863..2702f70455681 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 @@ -81,8 +81,11 @@ public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject /** {@link Long#MIN_VALUE} means no expiration is set. */ expireTimeTransferDelta = Long.MIN_VALUE; } - else + else { + initTime = System.currentTimeMillis(); + expireTimeTransferDelta = expireTime == 0 ? Long.MIN_VALUE : expireTime - initTime; + } this.cacheId = cacheId; this.key = key; diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java index 58b01951bd3b0..231576b5c34ba 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java @@ -342,7 +342,7 @@ private void checkSizeAfterLive() throws Exception { * @param gridCnt Number of nodes. * @throws Exception If failed. */ - private void checkSizeAfterLive(int gridCnt) throws Exception { + private void checkSizeAfterLive(int gridCnt) { for (int i = 0; i < gridCnt; ++i) { IgniteCache cache = jcache(i); From c37251c5d297febebc58f5331719ff70eb536b92 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Fri, 7 Aug 2026 20:33:26 +0300 Subject: [PATCH 05/15] minor refactor --- .../internal/processors/cache/GridCacheEntryInfo.java | 2 +- .../internal/processors/cache/GridCacheMapEntry.java | 2 +- .../cache/distributed/dht/GridDhtGetFuture.java | 4 ++-- .../cache/distributed/dht/GridDhtGetSingleFuture.java | 8 +++----- .../dht/preloader/GridDhtPartitionSupplier.java | 2 +- .../internal/processors/cache/GridCacheTestEntryEx.java | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) 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 2702f70455681..3a0d5dcf66a1f 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 @@ -76,7 +76,7 @@ public GridCacheEntryInfo() { } /** */ - public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long ttl, long expireTime) { + public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long expireTime, long ttl) { if (expireTime == 0) { /** {@link Long#MIN_VALUE} means no expiration is set. */ expireTimeTransferDelta = Long.MIN_VALUE; 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 09118e3aa9402..1eeb357681336 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 @@ -400,7 +400,7 @@ protected GridDhtLocalPartition localPartition() { CacheObject val0 = expireTime == 0 || expireTime <= U.currentTimeMillis() ? val : null; - info = new GridCacheEntryInfo(cctx.cacheId(), key, val0, ver, ttlExtras(), expireTime); + info = new GridCacheEntryInfo(cctx.cacheId(), key, val0, ver, expireTime, ttlExtras()); info.setNew(isStartVersion()); info.setDeleted(deletedUnlocked()); 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 7ca0776107230..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 @@ -506,8 +506,8 @@ private Collection toEntryInfos(Map map) assert val != null; - GridCacheEntryInfo info = new GridCacheEntryInfo( + return new GridCacheEntryInfo( cctx.cacheId(), key, skipVals ? null : val.value(), val.version(), - val.ttl(), - val.expireTime() + val.expireTime(), + val.ttl() ); - - return info; } /** 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 5fde5ed2440a3..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,7 +349,7 @@ public void handleDemandMessage(int topicId, UUID nodeId, GridDhtPartitionDemand if (!remainingParts.contains(part)) continue; - GridCacheEntryInfo info = new GridCacheEntryInfo(row.cacheId(), row.key(), row.value(), row.version(), 0, 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 86fcd4be96167..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,7 +269,7 @@ void recheckLock() { /** {@inheritDoc} */ @Override public GridCacheEntryInfo info() { - return new GridCacheEntryInfo(0, key(), val, version(), ttl(), expireTime()); + return new GridCacheEntryInfo(0, key(), val, version(), expireTime(), ttl()); } /** {@inheritDoc} */ From 7167732e84929aecc3da3ac48fdd33bc5252dd86 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Fri, 7 Aug 2026 20:39:40 +0300 Subject: [PATCH 06/15] fix --- .../ignite/internal/processors/cache/GridCacheMapEntry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1eeb357681336..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 @@ -398,7 +398,7 @@ protected GridDhtLocalPartition localPartition() { if (!obsolete()) { long expireTime = expireTimeExtras(); - CacheObject val0 = expireTime == 0 || expireTime <= U.currentTimeMillis() ? val : null; + CacheObject val0 = expireTime == 0 || expireTime > U.currentTimeMillis() ? val : null; info = new GridCacheEntryInfo(cctx.cacheId(), key, val0, ver, expireTime, ttlExtras()); From 17616fe072bda7fecc136f8b6575adf49f7c9029 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 16:21:33 +0300 Subject: [PATCH 07/15] fix --- .../processors/cache/GridCacheEntryInfo.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) 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 3a0d5dcf66a1f..1ade622dee3d7 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 @@ -53,7 +53,10 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { /** Base time to calculate {@link #expireTime()}. */ long initTime; - /** Expiration time delta to transfer. {@link Long#MIN_VALUE} means no expiration is set. */ + /** Expiration time delta to transfer. {@link Long#MIN_VALUE} means no expiration is set. In theory, calculating and + * comparing times could be biased by GC thread pauses. There might be chance to get negaive values. This would mean + * expired timeout and shouldn't be treated as disabled expiration. So, we use the farthest value as minimal chance + * to get met. */ @Order(4) long expireTimeTransferDelta = Long.MIN_VALUE; @@ -77,14 +80,18 @@ public GridCacheEntryInfo() { /** */ public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long expireTime, long ttl) { + assert expireTime >= 0; + if (expireTime == 0) { /** {@link Long#MIN_VALUE} means no expiration is set. */ expireTimeTransferDelta = Long.MIN_VALUE; } else { + // In theory, thread could be paused around here. Thus, the expiration delta becomes negative. + // This shouldn't be treated as disabled expiration. The correct behavior would be an expired timeout. initTime = System.currentTimeMillis(); - expireTimeTransferDelta = expireTime == 0 ? Long.MIN_VALUE : expireTime - initTime; + expireTimeTransferDelta = expireTime - initTime; } this.cacheId = cacheId; @@ -124,6 +131,8 @@ public void key(@Nullable KeyCacheObject key) { * @return Expire time. */ public long expireTime() { + assert (initTime == 0) == (expireTimeTransferDelta == Long.MIN_VALUE); + return expireTimeTransferDelta == Long.MIN_VALUE ? 0 : initTime + expireTimeTransferDelta; } From a459156aad1b23b446d1aeff71c43d9fc625da62 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 17:00:26 +0300 Subject: [PATCH 08/15] simplification --- .../processors/cache/GridCacheEntryInfo.java | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) 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 1ade622dee3d7..5501691bd3165 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 @@ -50,15 +50,12 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { @Order(3) long ttl; - /** Base time to calculate {@link #expireTime()}. */ + /** 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 is set. In theory, calculating and - * comparing times could be biased by GC thread pauses. There might be chance to get negaive values. This would mean - * expired timeout and shouldn't be treated as disabled expiration. So, we use the farthest value as minimal chance - * to get met. */ + /** Expiration time delta to transfer. */ @Order(4) - long expireTimeTransferDelta = Long.MIN_VALUE; + long expireTimeDelta; /** Entry version. */ @Order(5) @@ -72,7 +69,7 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { /** * Empty constructor for serialization purposes. - * see {@link #expireTimeTransferDelta}. + * see {@link #expireTimeDelta}. */ public GridCacheEntryInfo() { initTime = System.currentTimeMillis(); @@ -82,16 +79,10 @@ public GridCacheEntryInfo() { public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long expireTime, long ttl) { assert expireTime >= 0; - if (expireTime == 0) { - /** {@link Long#MIN_VALUE} means no expiration is set. */ - expireTimeTransferDelta = Long.MIN_VALUE; - } - else { - // In theory, thread could be paused around here. Thus, the expiration delta becomes negative. - // This shouldn't be treated as disabled expiration. The correct behavior would be an expired timeout. + if (expireTime != 0) { initTime = System.currentTimeMillis(); - expireTimeTransferDelta = expireTime - initTime; + expireTimeDelta = expireTime - initTime; } this.cacheId = cacheId; @@ -131,9 +122,9 @@ public void key(@Nullable KeyCacheObject key) { * @return Expire time. */ public long expireTime() { - assert (initTime == 0) == (expireTimeTransferDelta == Long.MIN_VALUE); + assert (initTime == 0L) == (expireTimeDelta == 0L); - return expireTimeTransferDelta == Long.MIN_VALUE ? 0 : initTime + expireTimeTransferDelta; + return initTime == 0L ? 0L : initTime + expireTimeDelta; } /** From 176f8a810a97152237746af55c03b4155c339d8c Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 17:00:26 +0300 Subject: [PATCH 09/15] simplification --- .../processors/cache/GridCacheEntryInfo.java | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) 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 1ade622dee3d7..6f412d5c3b398 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 @@ -50,15 +50,12 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { @Order(3) long ttl; - /** Base time to calculate {@link #expireTime()}. */ + /** 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 is set. In theory, calculating and - * comparing times could be biased by GC thread pauses. There might be chance to get negaive values. This would mean - * expired timeout and shouldn't be treated as disabled expiration. So, we use the farthest value as minimal chance - * to get met. */ + /** Expiration time delta to transfer. */ @Order(4) - long expireTimeTransferDelta = Long.MIN_VALUE; + long expireTimeDelta; /** Entry version. */ @Order(5) @@ -72,7 +69,7 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { /** * Empty constructor for serialization purposes. - * see {@link #expireTimeTransferDelta}. + * see {@link #expireTimeDelta}. */ public GridCacheEntryInfo() { initTime = System.currentTimeMillis(); @@ -82,16 +79,10 @@ public GridCacheEntryInfo() { public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject val, GridCacheVersion ver, long expireTime, long ttl) { assert expireTime >= 0; - if (expireTime == 0) { - /** {@link Long#MIN_VALUE} means no expiration is set. */ - expireTimeTransferDelta = Long.MIN_VALUE; - } - else { - // In theory, thread could be paused around here. Thus, the expiration delta becomes negative. - // This shouldn't be treated as disabled expiration. The correct behavior would be an expired timeout. + if (expireTime != 0) { initTime = System.currentTimeMillis(); - expireTimeTransferDelta = expireTime - initTime; + expireTimeDelta = expireTime - initTime; } this.cacheId = cacheId; @@ -131,9 +122,9 @@ public void key(@Nullable KeyCacheObject key) { * @return Expire time. */ public long expireTime() { - assert (initTime == 0) == (expireTimeTransferDelta == Long.MIN_VALUE); + assert initTime >= 0; - return expireTimeTransferDelta == Long.MIN_VALUE ? 0 : initTime + expireTimeTransferDelta; + return initTime == 0L ? 0L : initTime + expireTimeDelta; } /** From e612db7e990d219e9509de2d5356e54e1d9152a5 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 17:09:38 +0300 Subject: [PATCH 10/15] minor revert --- .../internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java index 231576b5c34ba..58b01951bd3b0 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/ttl/CacheTtlAbstractSelfTest.java @@ -342,7 +342,7 @@ private void checkSizeAfterLive() throws Exception { * @param gridCnt Number of nodes. * @throws Exception If failed. */ - private void checkSizeAfterLive(int gridCnt) { + private void checkSizeAfterLive(int gridCnt) throws Exception { for (int i = 0; i < gridCnt; ++i) { IgniteCache cache = jcache(i); From bc38d2b2324ef5c2e35f58de07ce89ded5a2192a Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 17:20:30 +0300 Subject: [PATCH 11/15] minor --- .../ignite/internal/processors/cache/GridCacheEntryInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6f412d5c3b398..2dca5b011b9de 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 @@ -119,7 +119,7 @@ public void key(@Nullable KeyCacheObject key) { } /** - * @return Expire time. + * @return Expire time >= 0. 0 means no expiration is set. */ public long expireTime() { assert initTime >= 0; From 0de4fe8987923679e2b02adedef9bff53607696b Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 19:30:49 +0300 Subject: [PATCH 12/15] fix --- .../processors/cache/GridCacheEntryInfo.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 2dca5b011b9de..a2b93a8b4b115 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 @@ -53,9 +53,13 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { /** Base time to calculate {@link #expireTime()}. 0 if no expiration is used. */ long initTime; - /** Expiration time delta to transfer. */ + /** + * Expiration time delta to transfer. In theory, here 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 used as one unrealistic chance to appear. + */ @Order(4) - long expireTimeDelta; + long expireTimeDelta = Long.MIN_VALUE; /** Entry version. */ @Order(5) @@ -80,6 +84,8 @@ public GridCacheEntryInfo(int cacheId, KeyCacheObject key, @Nullable CacheObject 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; @@ -124,7 +130,7 @@ public void key(@Nullable KeyCacheObject key) { public long expireTime() { assert initTime >= 0; - return initTime == 0L ? 0L : initTime + expireTimeDelta; + return expireTimeDelta == Long.MIN_VALUE ? 0L : initTime + expireTimeDelta; } /** From e009408706054fa6182b8e348dc533fd726e4ca7 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 19:33:23 +0300 Subject: [PATCH 13/15] minor comment --- .../ignite/internal/processors/cache/GridCacheEntryInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 a2b93a8b4b115..a1ebccd45e319 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 @@ -54,9 +54,9 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { long initTime; /** - * Expiration time delta to transfer. In theory, here we can get the calculating time delta thread paused causing + * Expiration time delta to transfer. 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 used as one unrealistic chance to appear. + * {@link Long#MIN_VALUE} is taken as one with unrealistic chance to appear. */ @Order(4) long expireTimeDelta = Long.MIN_VALUE; From f588f629661d73bab7f177479454ed6757562f6c Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 19:36:54 +0300 Subject: [PATCH 14/15] more minor comment --- .../internal/processors/cache/GridCacheEntryInfo.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 a1ebccd45e319..0939a6d860f63 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 @@ -54,9 +54,9 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { long initTime; /** - * Expiration time delta to transfer. 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. + * 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 expireTimeDelta = Long.MIN_VALUE; From 4d35a1f8c2e106ab0b086ab7a5eb62e7c45ada34 Mon Sep 17 00:00:00 2001 From: Steshin Vladimir Date: Sun, 9 Aug 2026 19:39:41 +0300 Subject: [PATCH 15/15] more minor comment --- .../ignite/internal/processors/cache/GridCacheEntryInfo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 0939a6d860f63..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 @@ -56,7 +56,8 @@ public class GridCacheEntryInfo implements CacheIdAware, Message { /** * 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. + * expiration. Correct behavior is expired timeout. {@link Long#MIN_VALUE} is taken as one with unrealistic chance + * to appear. */ @Order(4) long expireTimeDelta = Long.MIN_VALUE;