Skip to content

Commit

Permalink
BPlusTree: do not init old value when it is not used.
Browse files Browse the repository at this point in the history
  • Loading branch information
sboikov committed Jan 19, 2017
1 parent f6011a5 commit d854395
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 59 deletions.
Expand Up @@ -920,13 +920,13 @@ public CacheDataStoreImpl(
assert old.link() != 0 : old; assert old.link() != 0 : old;


if (pendingEntries != null && old.expireTime() != 0) if (pendingEntries != null && old.expireTime() != 0)
pendingEntries.remove(new PendingRow(old.expireTime(), old.link())); pendingEntries.removex(new PendingRow(old.expireTime(), old.link()));


rowStore.removeRow(old.link()); rowStore.removeRow(old.link());
} }


if (pendingEntries != null && expireTime != 0) if (pendingEntries != null && expireTime != 0)
pendingEntries.put(new PendingRow(expireTime, dataRow.link())); pendingEntries.putx(new PendingRow(expireTime, dataRow.link()));


updateIgfsMetrics(key, (old != null ? old.value() : null), val); updateIgfsMetrics(key, (old != null ? old.value() : null), val);
} }
Expand All @@ -950,7 +950,7 @@ public CacheDataStoreImpl(
assert dataRow.link() != 0 : dataRow; assert dataRow.link() != 0 : dataRow;


if (pendingEntries != null && dataRow.expireTime() != 0) if (pendingEntries != null && dataRow.expireTime() != 0)
pendingEntries.remove(new PendingRow(dataRow.expireTime(), dataRow.link())); pendingEntries.removex(new PendingRow(dataRow.expireTime(), dataRow.link()));


storageSize.decrementAndGet(); storageSize.decrementAndGet();


Expand Down Expand Up @@ -1242,6 +1242,15 @@ public CacheDataTree(
return compareKeys(row.key(), link); return compareKeys(row.key(), link);
} }


/** {@inheritDoc} */
@Override protected CacheDataRow getRow(BPlusIO<CacheSearchRow> io, long pageAddr, int idx)
throws IgniteCheckedException {
int hash = ((RowLinkIO)io).getHash(pageAddr, idx);
long link = ((RowLinkIO)io).getLink(pageAddr, idx);

return rowStore.dataRow(hash, link);
}

/** /**
* @param key Key. * @param key Key.
* @param link Link. * @param link Link.
Expand Down Expand Up @@ -1270,19 +1279,22 @@ private int compareKeys(KeyCacheObject key, final long link) throws IgniteChecke


int len = PageUtils.getInt(addr, 0); int len = PageUtils.getInt(addr, 0);


int size = Math.min(bytes.length, len); int lenCmp = Integer.compare(len, bytes.length);

if (lenCmp != 0)
return lenCmp;


addr += 5; // Skip length and type byte. addr += 5; // Skip length and type byte.


for (int i = 0; i < size; i++) { for (int i = 0; i < len; i++) {
byte b1 = PageUtils.getByte(addr, i); byte b1 = PageUtils.getByte(addr, i);
byte b2 = bytes[i]; byte b2 = bytes[i];


if (b1 != b2) if (b1 != b2)
return b1 > b2 ? 1 : -1; return b1 > b2 ? 1 : -1;
} }


return Integer.compare(len, bytes.length); return 0;
} }
} }
finally { finally {
Expand All @@ -1297,26 +1309,20 @@ private int compareKeys(KeyCacheObject key, final long link) throws IgniteChecke
byte[] bytes1 = other.key().valueBytes(cctx.cacheObjectContext()); byte[] bytes1 = other.key().valueBytes(cctx.cacheObjectContext());
byte[] bytes2 = key.valueBytes(cctx.cacheObjectContext()); byte[] bytes2 = key.valueBytes(cctx.cacheObjectContext());


int len = Math.min(bytes1.length, bytes2.length); int lenCmp = Integer.compare(bytes1.length, bytes2.length);


for (int i = 0; i < len; i++) { if (lenCmp != 0)
return lenCmp;

for (int i = 0; i < bytes1.length; i++) {
byte b1 = bytes1[i]; byte b1 = bytes1[i];
byte b2 = bytes2[i]; byte b2 = bytes2[i];


if (b1 != b2) if (b1 != b2)
return b1 > b2 ? 1 : -1; return b1 > b2 ? 1 : -1;
} }


return Integer.compare(bytes1.length, bytes2.length); return 0;
}

/** {@inheritDoc} */
@Override protected CacheDataRow getRow(BPlusIO<CacheSearchRow> io, long pageAddr, int idx)
throws IgniteCheckedException {
int hash = ((RowLinkIO)io).getHash(pageAddr, idx);
long link = ((RowLinkIO)io).getLink(pageAddr, idx);

return rowStore.dataRow(hash, link);
} }
} }


Expand Down
Expand Up @@ -322,7 +322,7 @@ else if (needBackIfRouting) {
assert p.oldRow == null; assert p.oldRow == null;


// Get old row in leaf page to reduce contention at upper level. // Get old row in leaf page to reduce contention at upper level.
p.oldRow = getRow(io, pageAddr, idx); p.oldRow = p.needOld ? getRow(io, pageAddr, idx) : (T)Boolean.TRUE;


p.finish(); p.finish();


Expand Down Expand Up @@ -1292,13 +1292,12 @@ public static void interruptAll() {


/** /**
* @param row Lookup row. * @param row Lookup row.
* @param bag Reuse bag.
* @return Removed row. * @return Removed row.
* @throws IgniteCheckedException If failed. * @throws IgniteCheckedException If failed.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final T removeCeil(L row, ReuseBag bag) throws IgniteCheckedException { public final T removeCeil(L row) throws IgniteCheckedException {
return doRemove(row, true, bag); return doRemove(row, true, true);
} }


/** /**
Expand All @@ -1307,20 +1306,31 @@ public final T removeCeil(L row, ReuseBag bag) throws IgniteCheckedException {
* @throws IgniteCheckedException If failed. * @throws IgniteCheckedException If failed.
*/ */
@Override public final T remove(L row) throws IgniteCheckedException { @Override public final T remove(L row) throws IgniteCheckedException {
return doRemove(row, false, null); return doRemove(row, false, true);
}

/**
* @param row Lookup row.
* @throws IgniteCheckedException If failed.
* @return {@code True} if removed row.
*/
public final boolean removex(L row) throws IgniteCheckedException {
Boolean res = (Boolean)doRemove(row, false, false);

return res != null ? res : false;
} }


/** /**
* @param row Lookup row. * @param row Lookup row.
* @param ceil If we can remove ceil row when we can not find exact. * @param ceil If we can remove ceil row when we can not find exact.
* @param bag Reuse bag. * @param needOld {@code True} if need return removed row.
* @return Removed row. * @return Removed row.
* @throws IgniteCheckedException If failed. * @throws IgniteCheckedException If failed.
*/ */
private T doRemove(L row, boolean ceil, ReuseBag bag) throws IgniteCheckedException { private T doRemove(L row, boolean ceil, boolean needOld) throws IgniteCheckedException {
checkDestroyed(); checkDestroyed();


Remove r = new Remove(row, ceil, bag); Remove r = new Remove(row, ceil, needOld);


try { try {
for (;;) { for (;;) {
Expand Down Expand Up @@ -1355,7 +1365,7 @@ private T doRemove(L row, boolean ceil, ReuseBag bag) throws IgniteCheckedExcept


assert r.isFinished(); assert r.isFinished();


return r.removed; return r.rmvd;
} }
} }
} }
Expand Down Expand Up @@ -1564,19 +1574,30 @@ public final int rootLevel() throws IgniteCheckedException {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override public final T put(T row) throws IgniteCheckedException { @Override public final T put(T row) throws IgniteCheckedException {
return put(row, null); return put(row, true);
}

/**
* @param row New value.
* @throws IgniteCheckedException If failed.
* @return {@code True} if replaced existing row.
*/
public boolean putx(T row) throws IgniteCheckedException {
Boolean res = (Boolean)put(row, false);

return res != null ? res : false;
} }


/** /**
* @param row Row. * @param row New value.
* @param bag Reuse bag. * @param needOld {@code True} If need return old value.
* @return Old row. * @return Old row.
* @throws IgniteCheckedException If failed. * @throws IgniteCheckedException If failed.
*/ */
public final T put(T row, ReuseBag bag) throws IgniteCheckedException { private T put(T row, boolean needOld) throws IgniteCheckedException {
checkDestroyed(); checkDestroyed();


Put p = new Put(row, bag); Put p = new Put(row, needOld);


try { try {
for (;;) { // Go down with retries. for (;;) { // Go down with retries.
Expand Down Expand Up @@ -2116,16 +2137,16 @@ private final class Put extends Get {
Bool needReplaceInner = FALSE; Bool needReplaceInner = FALSE;


/** */ /** */
private ReuseBag bag; private final boolean needOld;


/** /**
* @param row Row. * @param row Row.
* @param bag Reuse bag. * @param needOld {@code True} If need return old value.
*/ */
private Put(T row, ReuseBag bag) { private Put(T row, boolean needOld) {
super(row); super(row);


this.bag = bag; this.needOld = needOld;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
Expand Down Expand Up @@ -2234,7 +2255,7 @@ private void insertSimple(Page page, BPlusIO<L> io, long pageAddr, int idx)
*/ */
private L insertWithSplit(Page page, BPlusIO<L> io, final long pageAddr, int idx, int lvl) private L insertWithSplit(Page page, BPlusIO<L> io, final long pageAddr, int idx, int lvl)
throws IgniteCheckedException { throws IgniteCheckedException {
long fwdId = allocatePage(bag); long fwdId = allocatePage(null);


try (Page fwd = page(fwdId)) { try (Page fwd = page(fwdId)) {
// Need to check this before the actual split, because after the split we will have new forward page here. // Need to check this before the actual split, because after the split we will have new forward page here.
Expand Down Expand Up @@ -2281,7 +2302,7 @@ private L insertWithSplit(Page page, BPlusIO<L> io, final long pageAddr, int idx
} }


if (!hadFwd && lvl == getRootLevel()) { // We are splitting root. if (!hadFwd && lvl == getRootLevel()) { // We are splitting root.
long newRootId = allocatePage(bag); long newRootId = allocatePage(null);


try (Page newRoot = page(newRootId)) { try (Page newRoot = page(newRootId)) {
if (io.isLeaf()) if (io.isLeaf())
Expand Down Expand Up @@ -2350,7 +2371,7 @@ private final class Remove extends Get implements ReuseBag {
Bool needMergeEmptyBranch = FALSE; Bool needMergeEmptyBranch = FALSE;


/** Removed row. */ /** Removed row. */
private T removed; private T rmvd;


/** Current page. */ /** Current page. */
private Page page; private Page page;
Expand All @@ -2359,31 +2380,23 @@ private final class Remove extends Get implements ReuseBag {
private Object freePages; private Object freePages;


/** */ /** */
private ReuseBag bag; private final boolean needOld;


/** /**
* @param row Row. * @param row Row.
* @param ceil If we can remove ceil row when we can not find exact. * @param ceil If we can remove ceil row when we can not find exact.
* @param needOld {@code True} If need return old value.
*/ */
private Remove(L row, boolean ceil, ReuseBag bag) { private Remove(L row, boolean ceil, boolean needOld) {
super(row); super(row);


this.ceil = ceil; this.ceil = ceil;
this.bag = bag; this.needOld = needOld;
}

/**
* @return Reuse bag.
*/
private ReuseBag bag() {
return bag != null ? bag : this;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override public long pollFreePage() { @Override public long pollFreePage() {
assert bag == null;

if (freePages == null) if (freePages == null)
return 0; return 0;


Expand All @@ -2404,7 +2417,6 @@ private ReuseBag bag() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override public void addFreePage(long pageId) { @Override public void addFreePage(long pageId) {
assert pageId != 0; assert pageId != 0;
assert bag == null; // Otherwise we have to add the given pageId to that bag.


if (freePages == null) if (freePages == null)
freePages = pageId; freePages = pageId;
Expand Down Expand Up @@ -2523,7 +2535,7 @@ private boolean isInnerKeyInTail() throws IgniteCheckedException {
* @return {@code true} If already removed from leaf. * @return {@code true} If already removed from leaf.
*/ */
private boolean isRemoved() { private boolean isRemoved() {
return removed != null; return rmvd != null;
} }


/** /**
Expand Down Expand Up @@ -2799,7 +2811,7 @@ private void removeDataRowFromLeaf(Page page, BPlusIO<L> io, long pageAddr, int
assert !isRemoved(): "already removed"; assert !isRemoved(): "already removed";


// Detach the row. // Detach the row.
removed = getRow(io, pageAddr, idx); rmvd = needOld ? getRow(io, pageAddr, idx) : (T)Boolean.TRUE;


doRemove(page, io, pageAddr, cnt, idx); doRemove(page, io, pageAddr, cnt, idx);


Expand Down Expand Up @@ -3000,7 +3012,7 @@ private void freePage(Page page, long pageAddr, boolean release)
if (release) if (release)
writeUnlockAndClose(page, pageAddr); writeUnlockAndClose(page, pageAddr);


bag().addFreePage(pageId); addFreePage(pageId);
} }


/** /**
Expand All @@ -3021,7 +3033,7 @@ private void cutRoot(int lvl) throws IgniteCheckedException {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void reuseFreePages() throws IgniteCheckedException { private void reuseFreePages() throws IgniteCheckedException {
// If we have a bag, then it will be processed at the upper level. // If we have a bag, then it will be processed at the upper level.
if (reuseList != null && bag == null && freePages != null) if (reuseList != null && freePages != null)
reuseList.addForRecycle(this); reuseList.addForRecycle(this);
} }


Expand Down
Expand Up @@ -136,7 +136,6 @@ public H2Tree tree() {
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
@SuppressWarnings("StatementWithEmptyBody")
@Override public GridH2Row put(GridH2Row row) { @Override public GridH2Row put(GridH2Row row) {
try { try {
return tree.put(row); return tree.put(row);
Expand All @@ -146,6 +145,16 @@ public H2Tree tree() {
} }
} }


/** {@inheritDoc} */
@Override public boolean putx(GridH2Row row) {
try {
return tree.putx(row);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
}
}

/** {@inheritDoc} */ /** {@inheritDoc} */
@Override public GridH2Row remove(SearchRow row) { @Override public GridH2Row remove(SearchRow row) {
try { try {
Expand All @@ -156,6 +165,16 @@ public H2Tree tree() {
} }
} }


/** {@inheritDoc} */
@Override public void removex(SearchRow row) {
try {
tree.removex(row);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
}
}

/** {@inheritDoc} */ /** {@inheritDoc} */
@Override public double getCost(Session ses, int[] masks, TableFilter[] filters, int filter, SortOrder sortOrder) { @Override public double getCost(Session ses, int[] masks, TableFilter[] filters, int filter, SortOrder sortOrder) {
long rowCnt = getRowCountApproximation(); long rowCnt = getRowCountApproximation();
Expand Down

0 comments on commit d854395

Please sign in to comment.