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 2016/10/10 12:13:01 UTC
[05/50] [abbrv] ignite git commit: ignite-db-x - null locking
ignite-db-x - null locking
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e4ef2397
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e4ef2397
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e4ef2397
Branch: refs/heads/ignite-gg-8-io2-selNow
Commit: e4ef23979765364eca8991e33ef3d2cba6f5d878
Parents: 7d05c09
Author: Sergi Vladykin <se...@gmail.com>
Authored: Mon Sep 26 20:54:05 2016 +0300
Committer: Sergi Vladykin <se...@gmail.com>
Committed: Mon Sep 26 20:54:05 2016 +0300
----------------------------------------------------------------------
.../cache/database/freelist/FreeListImpl.java | 20 ++++++--
.../cache/database/freelist/PagesList.java | 18 ++++---
.../cache/database/tree/BPlusTree.java | 54 +++++++++++---------
.../cache/database/tree/util/PageHandler.java | 30 +++++++----
4 files changed, 77 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/e4ef2397/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl.java
index 748dea0..00a84db 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/FreeListImpl.java
@@ -52,6 +52,12 @@ public class FreeListImpl extends PagesList implements FreeList, ReuseList {
private static final Integer COMPLETE = Integer.MAX_VALUE;
/** */
+ private static final Integer FAIL_I = Integer.MIN_VALUE;
+
+ /** */
+ private static final Long FAIL_L = Long.MAX_VALUE;
+
+ /** */
private static final int MIN_PAGE_FREE_SPACE = 8;
/** */
@@ -318,7 +324,9 @@ public class FreeListImpl extends PagesList implements FreeList, ReuseList {
// If it is an existing page, we do not need to initialize it.
DataPageIO init = reuseBucket || pageId == 0L ? DataPageIO.VERSIONS.latest() : null;
- written = writePage(page, this, writeRow, init, wal, row, written);
+ written = writePage(page, this, writeRow, init, wal, row, written, FAIL_I);
+
+ assert written != FAIL_I; // We can't fail here.
}
}
while (written != COMPLETE);
@@ -334,15 +342,19 @@ public class FreeListImpl extends PagesList implements FreeList, ReuseList {
long nextLink;
try (Page page = pageMem.page(cacheId, pageId)) {
- nextLink = writePage(page, this, rmvRow, null, itemId);
+ nextLink = writePage(page, this, rmvRow, null, itemId, FAIL_L);
+
+ assert nextLink != FAIL_L; // Can't fail here.
}
- while (nextLink != 0) {
+ while (nextLink != 0L) {
itemId = PageIdUtils.itemId(nextLink);
pageId = PageIdUtils.pageId(nextLink);
try (Page page = pageMem.page(cacheId, pageId)) {
- nextLink = writePage(page, this, rmvRow, null, itemId);
+ nextLink = writePage(page, this, rmvRow, null, itemId, FAIL_L);
+
+ assert nextLink != FAIL_L; // Can't fail here.
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e4ef2397/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
index 7a6bfa2..9ee6746 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
@@ -52,6 +52,8 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA;
import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_IDX;
import static org.apache.ignite.internal.processors.cache.database.tree.io.PageIO.getPageId;
@@ -100,7 +102,7 @@ public abstract class PagesList extends DataStructure {
updateTail(bucket, tailId, page.id());
- return Boolean.TRUE;
+ return TRUE;
}
};
@@ -636,7 +638,7 @@ public abstract class PagesList extends DataStructure {
int idx = io.addPage(nextBuf, dataPageId);
// Here we should never write full page, because it is known to be new.
- next.fullPageWalRecordPolicy(Boolean.FALSE);
+ next.fullPageWalRecordPolicy(FALSE);
if (isWalDeltaRecordNeeded(wal, next))
wal.log(new PagesListInitNewPageRecord(
@@ -703,8 +705,8 @@ public abstract class PagesList extends DataStructure {
ByteBuffer nextBuf = writeLock(next);
if (locked == null) {
- locked = new ArrayList<>(2);
lockedBufs = new ArrayList<>(2);
+ locked = new ArrayList<>(2);
}
locked.add(next);
@@ -716,7 +718,7 @@ public abstract class PagesList extends DataStructure {
wal.log(new PagesListSetNextRecord(cacheId, pageId, nextId));
// Here we should never write full page, because it is known to be new.
- next.fullPageWalRecordPolicy(Boolean.FALSE);
+ next.fullPageWalRecordPolicy(FALSE);
if (isWalDeltaRecordNeeded(wal, next))
wal.log(new PagesListInitNewPageRecord(
@@ -848,9 +850,9 @@ public abstract class PagesList extends DataStructure {
if (prevId != 0L) {
try (Page prev = page(prevId)) {
// Lock pages from next to previous.
- Boolean ok = writePage(prev, this, cutTail, null, bucket);
+ Boolean ok = writePage(prev, this, cutTail, null, bucket, FALSE);
- assert ok;
+ assert ok == TRUE: ok;
}
if (initIoVers != null) {
@@ -984,9 +986,9 @@ public abstract class PagesList extends DataStructure {
if (prevId != 0L) { // Cut tail if we have a previous page.
try (Page prev = page(prevId)) {
- Boolean ok = writePage(prev, this, cutTail, null, bucket);
+ Boolean ok = writePage(prev, this, cutTail, null, bucket, FALSE);
- assert ok; // Because we keep lock on current tail and do a world consistency check.
+ assert ok == TRUE: ok; // Because we keep lock on current tail and do a world consistency check.
}
}
else // If we don't have a previous, then we are tail page of free list, just drop the stripe.
http://git-wip-us.apache.org/repos/asf/ignite/blob/e4ef2397/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
index fc89ec6..86d5b86 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
@@ -519,8 +519,8 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
};
/** */
- private final PageHandler<Void, Void> cutRoot = new PageHandler<Void, Void>() {
- @Override public Void run(Page meta, PageIO iox, ByteBuffer buf, Void ignore, int lvl)
+ private final PageHandler<Void, Bool> cutRoot = new PageHandler<Void, Bool>() {
+ @Override public Bool run(Page meta, PageIO iox, ByteBuffer buf, Void ignore, int lvl)
throws IgniteCheckedException {
// Safe cast because we should never recycle meta page until the tree is destroyed.
BPlusMetaIO io = (BPlusMetaIO)iox;
@@ -532,13 +532,13 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
if (needWalDeltaRecord(meta))
wal.log(new MetaPageCutRootRecord(cacheId, meta.id()));
- return null;
+ return TRUE;
}
};
/** */
- private final PageHandler<Long, Void> addRoot = new PageHandler<Long, Void>() {
- @Override public Void run(Page meta, PageIO iox, ByteBuffer buf, Long rootPageId, int lvl)
+ private final PageHandler<Long, Bool> addRoot = new PageHandler<Long, Bool>() {
+ @Override public Bool run(Page meta, PageIO iox, ByteBuffer buf, Long rootPageId, int lvl)
throws IgniteCheckedException {
assert rootPageId != null;
@@ -552,13 +552,13 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
if (needWalDeltaRecord(meta))
wal.log(new MetaPageAddRootRecord(cacheId, meta.id(), rootPageId));
- return null;
+ return TRUE;
}
};
/** */
- private final PageHandler<Long, Void> initRoot = new PageHandler<Long, Void>() {
- @Override public Void run(Page meta, PageIO iox, ByteBuffer buf, Long rootId, int lvl)
+ private final PageHandler<Long, Bool> initRoot = new PageHandler<Long, Bool>() {
+ @Override public Bool run(Page meta, PageIO iox, ByteBuffer buf, Long rootId, int lvl)
throws IgniteCheckedException {
assert rootId != null;
@@ -570,7 +570,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
if (needWalDeltaRecord(meta))
wal.log(new MetaPageInitRootRecord(cacheId, meta.id(), rootId));
- return null;
+ return TRUE;
}
};
@@ -646,7 +646,9 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
// Initialize meta page with new root page.
try (Page meta = page(metaPageId)) {
- writePage(meta, this, initRoot, BPlusMetaIO.VERSIONS.latest(), wal, rootId, 0);
+ Bool res = writePage(meta, this, initRoot, BPlusMetaIO.VERSIONS.latest(), wal, rootId, 0, FALSE);
+
+ assert res == TRUE: res;
}
}
@@ -823,7 +825,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
g.pageId = pageId;
g.fwdId = fwdId;
- Result res = readPage(page, this, search, g, lvl);
+ Result res = readPage(page, this, search, g, lvl, RETRY);
switch (res) {
case GO_DOWN:
@@ -1342,7 +1344,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
r.fwdId = fwdId;
r.backId = backId;
- Result res = readPage(page, this, search, r, lvl);
+ Result res = readPage(page, this, search, r, lvl, RETRY);
switch (res) {
case GO_DOWN_X:
@@ -1754,7 +1756,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
private Result askNeighbor(long pageId, Get g, boolean back) throws IgniteCheckedException {
try (Page page = page(pageId)) {
return readPage(page, this, askNeighbor, g,
- back ? TRUE.ordinal() : FALSE.ordinal());
+ back ? TRUE.ordinal() : FALSE.ordinal(), RETRY);
}
}
@@ -1778,7 +1780,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
p.pageId = pageId;
p.fwdId = fwdId;
- Result res = readPage(page, this, search, p, lvl);
+ Result res = readPage(page, this, search, p, lvl, RETRY);
switch (res) {
case GO_DOWN:
@@ -1791,7 +1793,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
if (p.needReplaceInner == TRUE) {
p.needReplaceInner = FALSE; // Protect from retries.
- res = writePage(page, this, replace, p, lvl);
+ res = writePage(page, this, replace, p, lvl, RETRY);
if (res != FOUND)
return res; // Need to retry.
@@ -1817,7 +1819,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
p.pageId = pageId;
p.fwdId = fwdId;
- return writePage(page, this, replace, p, lvl);
+ return writePage(page, this, replace, p, lvl, RETRY);
case NOT_FOUND: // Do insert.
assert lvl == p.btmLvl : "must insert at the bottom level";
@@ -1827,7 +1829,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
p.pageId = pageId;
p.fwdId = fwdId;
- return writePage(page, this, insert, p, lvl);
+ return writePage(page, this, insert, p, lvl, RETRY);
default:
return res;
@@ -2273,7 +2275,9 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
}
}
- writePage(meta, BPlusTree.this, addRoot, newRootId, lvl + 1);
+ Bool res = writePage(meta, BPlusTree.this, addRoot, newRootId, lvl + 1, FALSE);
+
+ assert res == TRUE: res;
return null; // We've just moved link up to root, nothing to return here.
}
@@ -2656,7 +2660,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
Page back = page(backId);
try {
- return writePage(back, BPlusTree.this, lockBackAndRemoveFromLeaf, this, 0);
+ return writePage(back, BPlusTree.this, lockBackAndRemoveFromLeaf, this, 0, RETRY);
}
finally {
if (canRelease(back, 0))
@@ -2671,7 +2675,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
private Result doRemoveFromLeaf() throws IgniteCheckedException {
assert page != null;
- return writePage(page, BPlusTree.this, removeFromLeaf, this, 0);
+ return writePage(page, BPlusTree.this, removeFromLeaf, this, 0, RETRY);
}
/**
@@ -2682,7 +2686,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
private Result doLockTail(int lvl) throws IgniteCheckedException {
assert page != null;
- return writePage(page, BPlusTree.this, lockTail, this, lvl);
+ return writePage(page, BPlusTree.this, lockTail, this, lvl, RETRY);
}
/**
@@ -2710,7 +2714,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
Page back = page(backId);
try {
- return writePage(back, BPlusTree.this, lockBackAndTail, this, lvl);
+ return writePage(back, BPlusTree.this, lockBackAndTail, this, lvl, RETRY);
}
finally {
if (canRelease(back, lvl))
@@ -2730,7 +2734,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
Page fwd = page(fwdId);
try {
- return writePage(fwd, BPlusTree.this, lockTailForward, this, lvl);
+ return writePage(fwd, BPlusTree.this, lockTailForward, this, lvl, RETRY);
}
finally {
// If we were not able to lock forward page as tail, release the page.
@@ -2964,7 +2968,9 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure {
* @throws IgniteCheckedException If failed.
*/
private void cutRoot(int lvl) throws IgniteCheckedException {
- writePage(meta, BPlusTree.this, cutRoot, null, lvl);
+ Bool res = writePage(meta, BPlusTree.this, cutRoot, null, lvl, FALSE);
+
+ assert res == TRUE: res;
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/e4ef2397/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/util/PageHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/util/PageHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/util/PageHandler.java
index bc071d7..5551b1f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/util/PageHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/util/PageHandler.java
@@ -34,10 +34,10 @@ import static java.lang.Boolean.TRUE;
*/
public abstract class PageHandler<X, R> {
/** */
- private static final PageHandler<Void, Void> NOOP = new PageHandler<Void, Void>() {
- @Override public Void run( Page page, PageIO io, ByteBuffer buf, Void arg, int intArg)
+ private static final PageHandler<Void, Boolean> NOOP = new PageHandler<Void, Boolean>() {
+ @Override public Boolean run( Page page, PageIO io, ByteBuffer buf, Void arg, int intArg)
throws IgniteCheckedException {
- return null;
+ return TRUE;
}
};
@@ -68,6 +68,7 @@ public abstract class PageHandler<X, R> {
* @param h Handler.
* @param arg Argument.
* @param intArg Argument of type {@code int}.
+ * @param lockFailed Result in case of lock failure due to page recycling.
* @return Handler result.
* @throws IgniteCheckedException If failed.
*/
@@ -76,12 +77,16 @@ public abstract class PageHandler<X, R> {
PageLockListener lockListener,
PageHandler<X, R> h,
X arg,
- int intArg
+ int intArg,
+ R lockFailed
) throws IgniteCheckedException {
lockListener.onBeforeReadLock(page);
ByteBuffer buf = page.getForRead();
+ if (buf == null)
+ return lockFailed;
+
try {
lockListener.onReadLock(page, buf);
@@ -101,6 +106,7 @@ public abstract class PageHandler<X, R> {
* @param h Handler.
* @param arg Argument.
* @param intArg Argument of type {@code int}.
+ * @param lockFailed Result in case of lock failure due to page recycling.
* @return Handler result.
* @throws IgniteCheckedException If failed.
*/
@@ -109,9 +115,10 @@ public abstract class PageHandler<X, R> {
PageLockListener lockListener,
PageHandler<X, R> h,
X arg,
- int intArg
+ int intArg,
+ R lockFailed
) throws IgniteCheckedException {
- return writePage(page, lockListener, h, null, null, arg, intArg);
+ return writePage(page, lockListener, h, null, null, arg, intArg, lockFailed);
}
/**
@@ -126,7 +133,9 @@ public abstract class PageHandler<X, R> {
PageIO init,
IgniteWriteAheadLogManager wal
) throws IgniteCheckedException {
- writePage(page, lockListener, NOOP, init, wal, null, 0);
+ Boolean res = writePage(page, lockListener, NOOP, init, wal, null, 0, FALSE);
+
+ assert res == TRUE: res; // It must be newly allocated page, can't be recycled.
}
/**
@@ -136,6 +145,7 @@ public abstract class PageHandler<X, R> {
* @param init IO for new page initialization or {@code null} if it is an existing page.
* @param arg Argument.
* @param intArg Argument of type {@code int}.
+ * @param lockFailed Result in case of lock failure due to page recycling.
* @return Handler result.
* @throws IgniteCheckedException If failed.
*/
@@ -146,7 +156,8 @@ public abstract class PageHandler<X, R> {
PageIO init,
IgniteWriteAheadLogManager wal,
X arg,
- int intArg
+ int intArg,
+ R lockFailed
) throws IgniteCheckedException {
lockListener.onBeforeWriteLock(page);
@@ -156,7 +167,8 @@ public abstract class PageHandler<X, R> {
ByteBuffer buf = page.getForWrite();
- assert buf != null;
+ if (buf == null)
+ return lockFailed;
try {
lockListener.onWriteLock(page, buf);