You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/01/30 17:47:21 UTC
[9/9] ignite git commit: ignite-3477 lock free freelist
ignite-3477 lock free freelist
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a4256544
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a4256544
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a4256544
Branch: refs/heads/ignite-3477-freelist
Commit: a4256544b6bee9be054fc04e7317240d8d66ff3e
Parents: 0745af2
Author: sboikov <sb...@gridgain.com>
Authored: Mon Jan 30 20:02:03 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon Jan 30 20:11:39 2017 +0300
----------------------------------------------------------------------
.../IgniteCacheDatabaseSharedManager.java | 2 +-
.../cache/database/freelist/DataPageList.java | 11 +-
.../cache/database/freelist/FreeListImpl2.java | 336 ++++++++++++++-----
.../cache/database/tree/io/DataPageIO.java | 28 +-
.../database/FreeListImpl2SelfTest.java | 12 +-
5 files changed, 289 insertions(+), 100 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/a4256544/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index b1da249..46df221 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@ -80,7 +80,7 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
* @throws IgniteCheckedException If failed.
*/
protected void initDataStructures() throws IgniteCheckedException {
- freeList = new FreeListImpl2(0, cctx.gridName(), pageMem, null, cctx.wal(), 0L, true);
+ freeList = new FreeListImpl2(log, 0, cctx.gridName(), pageMem, null, cctx.wal(), 0L, true);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/a4256544/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/DataPageList.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/DataPageList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/DataPageList.java
index 710164d..90884ad 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/DataPageList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/DataPageList.java
@@ -49,6 +49,8 @@ public class DataPageList {
/** */
private final DataPageIO io;
+ public volatile boolean needCompact;
+
/**
* @param pageMem Page memory.
*/
@@ -58,13 +60,18 @@ public class DataPageList {
io = DataPageIO.VERSIONS.latest();
}
- public void put(Page page) throws IgniteCheckedException {
+ public void put(Page page, int bucket, int stripe) throws IgniteCheckedException {
+ long pageAddr = page.pageAddress();
+
+ io.setBucket(pageAddr, bucket);
+ io.setStripe(pageAddr, stripe);
+
while (true) {
Head head = this.head;
Head newHead = new Head(page.id());
- io.setNextPageId(page.pageAddress(), head.pageId);
+ io.setNextPageId(pageAddr, head.pageId);
if (GridUnsafe.compareAndSwapObject(this, headOffset, head, newHead))
break;
http://git-wip-us.apache.org/repos/asf/ignite/blob/a4256544/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl2.java
index c6859f8..a85d40d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl2.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.processors.cache.database.freelist;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReferenceArray;
import org.apache.ignite.IgniteCheckedException;
@@ -37,6 +39,7 @@ import org.apache.ignite.internal.processors.cache.database.tree.reuse.ReuseList
import org.apache.ignite.internal.processors.cache.database.tree.reuse.ReuseListImpl;
import org.apache.ignite.internal.processors.cache.database.tree.util.PageHandler;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jsr166.LongAdder8;
import static org.apache.ignite.internal.processors.cache.database.tree.util.PageHandler.writePage;
@@ -66,7 +69,9 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
private final PageHandler<CacheDataRow, Boolean> updateRow = new UpdateRow();
- /** */
+ /**
+ *
+ */
private class UpdateRow extends PageHandler<CacheDataRow, Boolean> {
@Override public Boolean run(Page page, PageIO iox, long pageAddr, CacheDataRow row, int itemId)
throws IgniteCheckedException {
@@ -83,91 +88,104 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
/** */
private final PageHandler<Void, Boolean> compact = new Compact();
+ /**
+ *
+ */
private class Compact extends PageHandler<Void, Boolean> {
- @Override public Boolean run(Page page, PageIO iox, long pageAddr, Void row, int itemId)
- throws IgniteCheckedException {
- DataPageIO io = (DataPageIO)iox;
+ @Override public Boolean run(Page page, PageIO iox, long pageAddr, Void row, int itemId)
+ throws IgniteCheckedException {
+ DataPageIO io = (DataPageIO)iox;
- int freeSpace = io.getFreeSpace(pageAddr);
+ int freeSpace = io.getFreeSpace(pageAddr);
- int newFreeSpace = io.compact(pageAddr, freeSpace, pageSize());
+ int newFreeSpace = io.compact(pageAddr, freeSpace, pageSize());
- assert freeSpace == newFreeSpace;
+ assert freeSpace == newFreeSpace;
- if (newFreeSpace > MIN_PAGE_FREE_SPACE) {
- int newBucket = bucket(newFreeSpace);
+ if (newFreeSpace > MIN_PAGE_FREE_SPACE) {
+ int newBucket = bucket(newFreeSpace);
// System.out.println("End compact [freeSpace=" + freeSpace +
// ", newSpace=" + newFreeSpace +
// ", b=" + newBucket + ']');
- putInBucket(newBucket, page);
- }
+ putInBucket(newBucket, page);
+ }
// else
// System.out.println("End compact, no reuse [freeSpace=" + freeSpace +
// ", newSpace=" + newFreeSpace + ']');
- return Boolean.TRUE;
- }
- };
+ return Boolean.TRUE;
+ }
+ };
/** */
- private final PageHandler<Void, Boolean> compact2 = new Compact2();
+ private final PageHandler<Integer, Compact2Res> compact2 = new Compact2();
- private class Compact2 extends PageHandler<Void, Boolean> {
- @Override public Boolean run(Page page, PageIO iox, long pageAddr, Void ignore, int reqSpace)
+ /**
+ *
+ */
+ private class Compact2 extends PageHandler<Integer, Compact2Res> {
+ @Override public Compact2Res run(Page page, PageIO iox, long pageAddr, Integer b, int reqSpace)
throws IgniteCheckedException {
DataPageIO io = (DataPageIO)iox;
int freeSpace = io.getFreeSpace(pageAddr);
+ int newBucket = bucket(freeSpace);
+
+ if (newBucket == b)
+ return Compact2Res.BUCKET_NOT_CHANGED;
+
int newFreeSpace = io.compact(pageAddr, freeSpace, pageSize());
assert freeSpace == newFreeSpace;
if (newFreeSpace > MIN_PAGE_FREE_SPACE) {
if (newFreeSpace >= reqSpace)
- return Boolean.TRUE;
-
- int newBucket = bucket(newFreeSpace);
+ return Compact2Res.FOUND;
putInBucket(newBucket, page);
}
- return Boolean.FALSE;
+ return Compact2Res.MOVED;
}
};
/** */
private final PageHandler<CacheDataRow, Integer> writeRow = new WriteRow();
+ /**
+ *
+ */
private class WriteRow extends PageHandler<CacheDataRow, Integer> {
- @Override public Integer run(Page page, PageIO iox, long pageAddr, CacheDataRow row, int written)
- throws IgniteCheckedException {
- DataPageIO io = (DataPageIO)iox;
-
- int rowSize = getRowSize(row);
- int oldFreeSpace = io.getFreeSpace(pageAddr);
+ @Override public Integer run(Page page, PageIO iox, long pageAddr, CacheDataRow row, int written)
+ throws IgniteCheckedException {
+ DataPageIO io = (DataPageIO)iox;
- assert oldFreeSpace > 0 : oldFreeSpace;
+ int rowSize = getRowSize(row);
+ int oldFreeSpace = io.getFreeSpace(pageAddr);
- // If the full row does not fit into this page write only a fragment.
- written = (written == 0 && oldFreeSpace >= rowSize) ? addRow(page, pageAddr, io, row, rowSize):
- addRowFragment(page, pageAddr, io, row, written, rowSize);
+ assert oldFreeSpace > 0 : oldFreeSpace;
- // Reread free space after update.
- int newFreeSpace = io.getFreeSpace(pageAddr);
+ // If the full row does not fit into this page write only a fragment.
+ written = (written == 0 && oldFreeSpace >= rowSize) ? addRow(page, pageAddr, io, row, rowSize):
+ addRowFragment(page, pageAddr, io, row, written, rowSize);
- if (newFreeSpace > MIN_PAGE_FREE_SPACE) {
- int bucket = bucket(newFreeSpace);
+ // Reread free space after update.
+ //int newFreeSpace = io.getFreeSpace(pageAddr);
+ int newFreeSpace = Math.max(io.getFreeSpace(pageAddr), io.getFreeSpace2(pageAddr));
- putInBucket(bucket, page);
- }
+ if (newFreeSpace > MIN_PAGE_FREE_SPACE) {
+ int bucket = bucket(newFreeSpace);
- // Avoid boxing with garbage generation for usual case.
- return written == rowSize ? COMPLETE : written;
+ putInBucket(bucket, page);
}
+ // Avoid boxing with garbage generation for usual case.
+ return written == rowSize ? COMPLETE : written;
+ }
+
/**
* @param page Page.
* @param pageAddr Page address.
@@ -218,6 +236,9 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
/** */
private final PageHandler<Void, Long> rmvRow = new RemoveRow();
+ /**
+ *
+ */
private class RemoveRow extends PageHandler<Void, Long> {
@Override public Long run(Page page, PageIO iox, long pageAddr, Void arg, int itemId)
throws IgniteCheckedException {
@@ -225,13 +246,34 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
int oldFreeSpace = io.getFreeSpace(pageAddr);
- assert oldFreeSpace >= 0: oldFreeSpace;
+ assert oldFreeSpace >= 0 : oldFreeSpace;
long nextLink = io.removeRow(pageAddr, itemId, pageSize());
int newFreeSpace = io.getFreeSpace(pageAddr);
- assert newFreeSpace > oldFreeSpace;
+ //assert newFreeSpace > oldFreeSpace : "n=" + newFreeSpace + ", o=" + oldFreeSpace;
+
+ if (newFreeSpace > MIN_PAGE_FREE_SPACE) {
+ int curBucket = io.getBucket(pageAddr);
+
+ assert curBucket == -1 || (curBucket >= 0 && curBucket < BUCKETS) : curBucket;
+
+ if (curBucket >= 0) {
+ int newBucket = bucket(newFreeSpace);
+
+ if ((newBucket != curBucket)) {
+ int stripe = io.getStripe(pageAddr);
+
+ assert stripe >= 0 && stripe < STACKS_PER_BUCKET : stripe;
+
+ DataPageList list = (DataPageList)buckets[curBucket].get(stripe);
+
+ if (list != null)
+ list.needCompact = true;
+ }
+ }
+ }
// For common case boxed 0L will be cached inside of Long, so no garbage will be produced.
return nextLink;
@@ -248,6 +290,16 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
private final ReuseListImpl reuseList;
+ private LongAdder8 scanCnt = new LongAdder8();
+ private LongAdder8 scanCntSuccess = new LongAdder8();
+ private LongAdder8 scanBuckets = new LongAdder8();
+
+ private LongAdder8 syncClearCnt = new LongAdder8();
+ private LongAdder8 syncClearSuccess = new LongAdder8();
+ private LongAdder8 syncClearBuckets = new LongAdder8();
+ private LongAdder8 syncClearLists = new LongAdder8();
+ private LongAdder8 syncClearPages = new LongAdder8();
+
/**
* @param cacheId Cache ID.
* @param name Name (for debug purpose).
@@ -259,6 +311,7 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
* @throws IgniteCheckedException If failed.
*/
public FreeListImpl2(
+ final IgniteLogger log,
int cacheId,
String name,
PageMemory pageMem,
@@ -267,6 +320,7 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
long metaPageId,
boolean initNew) throws IgniteCheckedException {
super(cacheId, pageMem, wal);
+ this.log = log;
this.reuseList = new ReuseListImpl(cacheId, name, pageMem, wal, 0, true);
int pageSize = pageMem.pageSize();
@@ -317,6 +371,53 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
compacter.setDaemon(true);
compacter.start();
+
+ Thread dump = new Thread(new Runnable() {
+ @Override public void run() {
+ try {
+ while (!Thread.currentThread().isInterrupted()) {
+ {
+ long scanCnt0 = scanCnt.sumThenReset();
+
+ if (scanCnt0 > 0) {
+ long scanCntSuccess0 = scanCntSuccess.sumThenReset();
+ long scanBuckets0 = scanBuckets.sumThenReset();
+
+ log.info("Bucket scans [total=" + scanCnt0 +
+ ", success=" + scanCntSuccess0 +
+ ", success %=" + scanCntSuccess0 / (double)scanCnt0 +
+ ", avgBuckets=" + scanBuckets0 / (double)scanCnt0 + ']');
+ }
+ }
+
+ long syncClearCnt0 = syncClearCnt.sumThenReset();
+
+ if (syncClearCnt0 > 0) {
+ long syncClearSuccess0 = syncClearSuccess.sumThenReset();
+ long syncClearBuckets0 = syncClearBuckets.sumThenReset();
+ long syncClearLists0 = syncClearLists.sumThenReset();
+ long syncClearPages0 = syncClearPages.sumThenReset();
+
+ log.info("Sync clear [total=" + syncClearCnt0 +
+ ", success=" + syncClearSuccess0 +
+ ", success %=" + syncClearSuccess0 / (double)syncClearCnt0 +
+ ", avgBuckets=" + syncClearBuckets0 / (double)syncClearCnt0 +
+ ", avgLists=" + syncClearLists0 / (double)syncClearCnt0 +
+ ", avgPages=" + syncClearPages0 / (double)syncClearCnt0 +
+ ']');
+ }
+
+ Thread.sleep(5000);
+ }
+ }
+ catch (Exception e) {
+ if (!(e instanceof InterruptedException))
+ e.printStackTrace();
+ }
+ }
+ });
+ dump.setDaemon(true);
+ dump.start();
}
private void putInBucket(int bucket, Page page) throws IgniteCheckedException {
@@ -330,7 +431,7 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
if (list != null) {
//System.out.println(Thread.currentThread().getName() + " put in bucket [b=" + bucket + ", stripe=" + idx + ']');
- list.put(page);
+ list.put(page, bucket, idx);
return;
}
@@ -434,12 +535,14 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
for (int i = 0; i < stacks.length(); i++) {
DataPageList pageList = stacks.get(i);
- if (pageList != null) {
+ if (pageList != null && pageList.needCompact) {
boolean take = stacks.compareAndSet(i, pageList, null);
if (take) {
compactStack(pageList);
+ pageList.needCompact = false;
+
stacks.set(i, pageList);
}
}
@@ -471,84 +574,139 @@ public class FreeListImpl2 extends DataStructure implements FreeList, ReuseList
int written = 0;
do {
- int freeSpace = Math.min(MIN_SIZE_FOR_DATA_PAGE, rowSize - written);
+ final int freeSpace = Math.min(MIN_SIZE_FOR_DATA_PAGE, rowSize - written);
- int bucket = bucket(freeSpace);
+ final int bucket = bucket(freeSpace);
Page foundPage = null;
+ int cntr = 0;
+
// TODO: properly handle reuse bucket.
for (int b = bucket; b < BUCKETS; b++) {
+ cntr++;
+
foundPage = takeFromBucket(b);
if (foundPage != null)
break;
}
- if (locCompact && foundPage == null && bucket > 0 && cg.compareAndSet(false, true)) {
- try {
- for (int b = 0; b < bucket; b++) {
- AtomicReferenceArray<DataPageList> stacks = buckets[b];
+ scanCnt.increment();
+ scanBuckets.add(cntr);
+
+ if (foundPage != null)
+ scanCntSuccess.increment();
+
+ if (foundPage == null && bucket > 0)
+ foundPage = syncClear(freeSpace, bucket);
+
+ try (Page page = foundPage == null ? allocateDataPage(row.partition()) : foundPage) {
+ // If it is an existing page, we do not need to initialize it.
+ DataPageIO init = foundPage == null ? DataPageIO.VERSIONS.latest() : null;
+
+ written = writePage(pageMem, page, this, writeRow, init, wal, row, written, FAIL_I);
+
+ assert written != FAIL_I; // We can't fail here.
+ }
+ }
+ while (written != COMPLETE);
+ }
+
+ enum Compact2Res {
+ FOUND,
+ MOVED,
+ BUCKET_NOT_CHANGED
+ }
+
+ private Page syncClear(final int freeSpace, final int bucket) throws IgniteCheckedException {
+ if (locCompact && cg.compareAndSet(false, true)) {
+ int buckets = 0;
+ int lists = 0;
+ int pages = 0;
+
+ boolean res = false;
+
+ try {
+ for (int b = 0; b < bucket; b++) {
+ buckets++;
+
+ AtomicReferenceArray<DataPageList> stacks = this.buckets[b];
+
+ final Integer B = b;
+
+ for (int i = 0; i < STACKS_PER_BUCKET; i++) {
+ DataPageList pageList = stacks.get(i);
+
+ if (pageList != null && pageList.needCompact) {
+ lists++;
+
+ boolean take = stacks.compareAndSet(i, pageList, null);
+
+ if (take) {
+ Page page;
- for (int i = 0; i < STACKS_PER_BUCKET; i++) {
- DataPageList pageList = stacks.get(i);
+ List<Page> mvPages = null;
- if (pageList != null) {
- boolean take = stacks.compareAndSet(i, pageList, null);
+ try {
+ while ((page = pageList.take(cacheId)) != null) {
+ pages++;
- if (take) {
- Page page;
+ Compact2Res found = writePage(pageMem,
+ page,
+ this,
+ compact2,
+ null,
+ wal,
+ B,
+ freeSpace,
+ null);
- try {
- while ((page = pageList.take(cacheId)) != null) {
- Boolean found = writePage(pageMem,
- page,
- this,
- compact2,
- null,
- wal,
- null,
- freeSpace,
- null);
+ assert found != null;
- assert found != null;
+ if (found == Compact2Res.FOUND) {
+ res = true;
- if (found) {
- foundPage = page;
+ return page;
+ }
+ else if (found == Compact2Res.BUCKET_NOT_CHANGED) {
+ if (mvPages == null)
+ mvPages = new ArrayList<>();
- break;
- }
+ mvPages.add(page);
}
}
- finally {
- stacks.set(i, pageList);
+ }
+ finally {
+ if (mvPages != null) {
+ for (int p = 0; p < mvPages.size(); p++)
+ pageList.put(mvPages.get(p), b, i);
}
+
+ if (!res)
+ pageList.needCompact = false;
+
+ stacks.set(i, pageList);
}
}
-
- if (foundPage != null)
- break;
}
-
- if (foundPage != null)
- break;
}
}
- finally {
- cg.set(false);
- }
}
+ finally {
+ if (res)
+ syncClearSuccess.increment();
- try (Page page = foundPage == null ? allocateDataPage(row.partition()) : foundPage) {
- // If it is an existing page, we do not need to initialize it.
- DataPageIO init = foundPage == null ? DataPageIO.VERSIONS.latest() : null;
-
- written = writePage(pageMem, page, this, writeRow, init, wal, row, written, FAIL_I);
+ syncClearCnt.increment();
+ syncClearBuckets.add(buckets);
+ syncClearLists.add(lists);
+ syncClearPages.add(pages);
- assert written != FAIL_I; // We can't fail here.
+ cg.set(false);
}
}
- while (written != COMPLETE);
+
+ return null;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/a4256544/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/DataPageIO.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/DataPageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/DataPageIO.java
index 5618a8c..ac2cf13 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/DataPageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/DataPageIO.java
@@ -54,7 +54,13 @@ public class DataPageIO extends PageIO {
private static final int NEXT_PAGE_ID_OFF = COMMON_HEADER_END;
/** */
- private static final int FREE_LIST_PAGE_ID_OFF = NEXT_PAGE_ID_OFF + 8;
+ private static final int BUCKET_OFF = NEXT_PAGE_ID_OFF + 8;
+
+ /** */
+ private static final int STRIPE_OFF = BUCKET_OFF + 4;
+
+ /** */
+ private static final int FREE_LIST_PAGE_ID_OFF = STRIPE_OFF + 4;
/** */
private static final int FREE_SPACE_OFF = FREE_LIST_PAGE_ID_OFF + 8;
@@ -99,6 +105,8 @@ public class DataPageIO extends PageIO {
setEmptyPage(pageAddr, pageSize);
setFreeListPageId(pageAddr, 0L);
+ setBucket(pageAddr, -1);
+ setStripe(pageAddr, -1);
}
/**
@@ -144,6 +152,22 @@ public class DataPageIO extends PageIO {
return PageUtils.getLong(pageAddr, NEXT_PAGE_ID_OFF);
}
+ public void setBucket(long pageAddr, int bucket) {
+ PageUtils.putInt(pageAddr, BUCKET_OFF, bucket);
+ }
+
+ public int getBucket(long pageAddr) {
+ return PageUtils.getInt(pageAddr, BUCKET_OFF);
+ }
+
+ public void setStripe(long pageAddr, int stripe) {
+ PageUtils.putInt(pageAddr, STRIPE_OFF, stripe);
+ }
+
+ public int getStripe(long pageAddr) {
+ return PageUtils.getInt(pageAddr, STRIPE_OFF);
+ }
+
/**
* @param pageAddr Page address.
* @param dataOff Data offset.
@@ -218,7 +242,7 @@ public class DataPageIO extends PageIO {
int indirectCnt = getIndirectCount(pageAddr);
int firstEntryOff = getFirstEntryOffset(pageAddr);
- return firstEntryOff - (ITEMS_OFF + ITEM_SIZE * (directCnt + indirectCnt));
+ return firstEntryOff - (ITEMS_OFF + ITEM_SIZE * (directCnt + indirectCnt)) - (ITEM_SIZE + PAYLOAD_LEN_SIZE + LINK_SIZE);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/a4256544/modules/core/src/test/java/org/apache/ignite/internal/processors/database/FreeListImpl2SelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/FreeListImpl2SelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/FreeListImpl2SelfTest.java
index 6bac890..ce3595e 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/FreeListImpl2SelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/FreeListImpl2SelfTest.java
@@ -90,7 +90,7 @@ public class FreeListImpl2SelfTest extends GridCommonAbstractTest {
public void testCompact() throws Exception {
pageMem = createPageMemory(1024);
- FreeListImpl2 fl = new FreeListImpl2(1, "freelist", pageMem, null, null, 0, true);
+ FreeListImpl2 fl = new FreeListImpl2(log, 1, "freelist", pageMem, null, null, 0, true);
fl.rnd = new Random();
for (int iter = 0; iter < 100_000; iter++) {
@@ -121,7 +121,7 @@ public class FreeListImpl2SelfTest extends GridCommonAbstractTest {
public void testCompact1() throws Exception {
pageMem = createPageMemory(1024);
- FreeListImpl2 fl = new FreeListImpl2(1, "freelist", pageMem, null, null, 0, true);
+ FreeListImpl2 fl = new FreeListImpl2(log, 1, "freelist", pageMem, null, null, 0, true);
fl.rnd = new Random(1);
fl.log = log;
@@ -171,7 +171,7 @@ public class FreeListImpl2SelfTest extends GridCommonAbstractTest {
assert id != 0;
- pl.put(pageMem.page(1, id));
+ pl.put(pageMem.page(1, id), 0, 0);
ids.push(id);
}
@@ -206,7 +206,7 @@ public class FreeListImpl2SelfTest extends GridCommonAbstractTest {
System.out.println("Iter: " + i);
for (Long id : ids)
- pl.put(pageMem.page(1, id));
+ pl.put(pageMem.page(1, id), 0, 0);
final int THREADS = 16;
@@ -258,7 +258,7 @@ public class FreeListImpl2SelfTest extends GridCommonAbstractTest {
System.out.println("Iter: " + i);
for (Long id : ids)
- pl.put(pageMem.page(1, id));
+ pl.put(pageMem.page(1, id), 0, 0);
final int THREADS = 16;
@@ -279,7 +279,7 @@ public class FreeListImpl2SelfTest extends GridCommonAbstractTest {
takeCnt.incrementAndGet();
if (ThreadLocalRandom.current().nextBoolean()) {
- pl.put(page);
+ pl.put(page, 0, 0);
putCnt.incrementAndGet();
}