diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java index 3d41f3ad09504..48a3328d0469b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java @@ -1792,22 +1792,13 @@ private void clearPendingEntries(GridCacheContext cctx, CacheDataRow oldRow) CacheDataRow row = dataTree.findOne(new SearchRow(cacheId, key), CacheDataRowAdapter.RowData.NO_KEY); - afterRowFound(row, key); - - return row; - } - - /** - * @param row Row. - * @param key Key. - * @throws IgniteCheckedException If failed. - */ - private void afterRowFound(@Nullable CacheDataRow row, KeyCacheObject key) throws IgniteCheckedException { if (row != null) { row.key(key); grp.dataRegion().evictionTracker().touchPage(row.link()); } + + return row; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java index 84fd0188de32f..04454d05acbac 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/FairFifoPageEvictionTracker.java @@ -55,7 +55,12 @@ public FairFifoPageEvictionTracker( } /** {@inheritDoc} */ - @Override public synchronized void touchPage(long pageId) throws IgniteCheckedException { + @Override protected void initPage(long pageId) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public synchronized void touchPage(long pageId) { pageUsageList.addLast(PageIdUtils.pageIndex(pageId)); } @@ -65,7 +70,7 @@ public FairFifoPageEvictionTracker( } /** {@inheritDoc} */ - @Override public synchronized void forgetPage(long pageId) throws IgniteCheckedException { + @Override public synchronized void forgetPage(long pageId) { // No-op. } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java index d212fcec88b5a..4409e35e7446b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/NoOpPageEvictionTracker.java @@ -16,7 +16,6 @@ */ package org.apache.ignite.internal.processors.cache.persistence.evict; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; /** @@ -34,17 +33,17 @@ public class NoOpPageEvictionTracker implements PageEvictionTracker { } /** {@inheritDoc} */ - @Override public void touchPage(long pageId) throws IgniteCheckedException { + @Override public void touchPage(long pageId) { // No-op. } /** {@inheritDoc} */ - @Override public void evictDataPage() throws IgniteCheckedException { + @Override public void evictDataPage() { // No-op. } /** {@inheritDoc} */ - @Override public void forgetPage(long pageId) throws IgniteCheckedException { + @Override public void forgetPage(long pageId) { // No-op. } @@ -54,7 +53,7 @@ public class NoOpPageEvictionTracker implements PageEvictionTracker { } /** {@inheritDoc} */ - @Override public void trackFragmentPage(long pageId, long prevPageId, boolean isHeadPage) throws IgniteCheckedException { + @Override public void trackFragmentPage(long pageId, long prevPageId, boolean isHeadPage) { // No-op. } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java index 07a97e8e4fbbd..2330c0942662d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageAbstractEvictionTracker.java @@ -185,7 +185,10 @@ int pageIdx(int trackingIdx) { } /** {@inheritDoc} */ - @Override public void trackFragmentPage(long pageId, long prevPageId, boolean isHeadPage) throws IgniteCheckedException { + @Override public void trackFragmentPage(long pageId, long prevPageId, boolean isHeadPage) { + if (isHeadPage) + initPage(pageId); + // Do nothing if called for tail page. if (prevPageId == 0) return; @@ -200,6 +203,9 @@ int pageIdx(int trackingIdx) { } } + /** */ + protected abstract void initPage(long pageId); + /** * Determine tail page tracking index given page id of previously written fragment. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java index 5954137fc40a7..82970fb52521c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/PageEvictionTracker.java @@ -28,9 +28,8 @@ public interface PageEvictionTracker extends LifecycleAware { * Call this method when data page is accessed. * * @param pageId Page id. - * @throws IgniteCheckedException In case of page memory error. */ - public void touchPage(long pageId) throws IgniteCheckedException; + public void touchPage(long pageId); /** * Check if page eviction is required according to the configured policy. @@ -53,9 +52,8 @@ public interface PageEvictionTracker extends LifecycleAware { * Call this method when last entry is removed from data page. * * @param pageId Page id. - * @throws IgniteCheckedException In case of page memory error. */ - public void forgetPage(long pageId) throws IgniteCheckedException; + public void forgetPage(long pageId); /** * Call this method when data page containing fragment of row is written. @@ -63,7 +61,6 @@ public interface PageEvictionTracker extends LifecycleAware { * @param pageId Page id. * @param prevPageId Page id of previous fragment. 0 if called for the tail fragment (written first). * @param isHeadPage True if head fragment (written last) of row is written, False otherwise. - * @throws IgniteCheckedException In case of page memory error. */ - public void trackFragmentPage(long pageId, long prevPageId, boolean isHeadPage) throws IgniteCheckedException; + public void trackFragmentPage(long pageId, long prevPageId, boolean isHeadPage); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java index 80634ed878f5a..01300ffb73fa0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/Random2LruPageEvictionTracker.java @@ -80,35 +80,46 @@ public Random2LruPageEvictionTracker( } /** {@inheritDoc} */ - @Override public void touchPage(long pageId) throws IgniteCheckedException { + @Override public void touchPage(long pageId) { int pageIdx = PageIdUtils.pageIndex(pageId); - - long latestTs = compactTimestamp(U.currentTimeMillis()); - - assert latestTs >= 0 && latestTs < Integer.MAX_VALUE; + int trackingIdx = trackingIdx(pageIdx); + long trackingPtr = trackingArrPtr + trackingIdx * 8L; boolean success; do { - int trackingIdx = trackingIdx(pageIdx); - - long trackingData = GridUnsafe.getLongVolatile(null, trackingArrPtr + trackingIdx * 8L); + long trackingData = GridUnsafe.getLongVolatile(null, trackingPtr); int firstTs = first(trackingData); - assert firstTs >= 0 : "[firstTs=" + firstTs + ", trackingData=" + trackingData + "]"; + if (firstTs <= 0) // Concurrently evicted. + return; + + long ts = compactTimestamp(U.currentTimeMillis()); + + assert ts >= 0 && ts < Integer.MAX_VALUE; int secondTs = second(trackingData); long newTrackingData; if (firstTs <= secondTs) - newTrackingData = U.toLong((int)latestTs, secondTs); + newTrackingData = U.toLong((int)ts, secondTs); else - newTrackingData = U.toLong(firstTs, (int)latestTs); + newTrackingData = U.toLong(firstTs, (int)ts); + + success = GridUnsafe.compareAndSwapLong(null, trackingPtr, trackingData, newTrackingData); + } + while (!success); + } + + /** */ + @Override protected void initPage(long pageId) { + int ts = (int)compactTimestamp(U.currentTimeMillis()); + + long trackingPtr = trackingArrPtr + trackingIdx(PageIdUtils.pageIndex(pageId)) * 8L; - success = GridUnsafe.compareAndSwapLong(null, trackingArrPtr + trackingIdx * 8L, trackingData, newTrackingData); - } while (!success); + GridUnsafe.compareAndSwapLong(null, trackingPtr, 0, U.toLong(ts, 0)); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java index cd690e0af7314..b940681403c15 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/evict/RandomLruPageEvictionTracker.java @@ -82,14 +82,30 @@ public RandomLruPageEvictionTracker( } /** {@inheritDoc} */ - @Override public void touchPage(long pageId) throws IgniteCheckedException { - int pageIdx = PageIdUtils.pageIndex(pageId); + @Override public void touchPage(long pageId) { + long trackingPtr = trackingArrPtr + trackingIdx(PageIdUtils.pageIndex(pageId)) * 4L; + + boolean success; + + do { + int trackingData = GridUnsafe.getIntVolatile(null, trackingPtr); + + if (trackingData <= 0) // Concurrently evicted. + return; + + long ts = compactTimestamp(U.currentTimeMillis()); - long res = compactTimestamp(U.currentTimeMillis()); + assert ts >= 0 && ts < Integer.MAX_VALUE; + + success = GridUnsafe.compareAndSwapInt(null, trackingPtr, trackingData, (int)ts); + } while (!success); + } - assert res >= 0 && res < Integer.MAX_VALUE; + /** */ + @Override protected void initPage(long pageId) { + int ts = (int)compactTimestamp(U.currentTimeMillis()); - GridUnsafe.putIntVolatile(null, trackingArrPtr + trackingIdx(pageIdx) * 4L, (int)res); + GridUnsafe.compareAndSwapInt(null, trackingArrPtr + trackingIdx(PageIdUtils.pageIndex(pageId)) * 4L, 0, ts); } /** {@inheritDoc} */