提交 7dd14b7c 编写于 作者: V Vlad Ilyushchenko

GRIFFIN: "order by" optimisation

上级 494fb53f
......@@ -1931,8 +1931,7 @@ public class TableWriter implements Closeable {
// For simplicity use partitionLo, which can be
// translated to directory name when needed
if (txPartitionCount++ > 0) {
txPendingPartitionSizes.putLong(transientRowCount);
txPendingPartitionSizes.putLong(maxTimestamp);
txPendingPartitionSizes.putLong128(transientRowCount, maxTimestamp);
}
fixedRowCount += transientRowCount;
txPrevTransientRowCount = transientRowCount;
......
......@@ -66,13 +66,6 @@ public class VirtualMemory implements Closeable {
return STRING_LENGTH_BYTES + s.length() * 2;
}
private static void copyStrChars(CharSequence value, int pos, int len, long address) {
for (int i = 0; i < len; i++) {
char c = value.charAt(i + pos);
Unsafe.getUnsafe().putChar(address + 2 * i, c);
}
}
public long addressOf(long offset) {
if (roOffsetLo < offset && offset < roOffsetHi) {
return absolutePointer + offset;
......@@ -396,6 +389,43 @@ public class VirtualMemory implements Closeable {
}
}
public final void putInt(int value) {
if (pageHi - appendPointer > 3) {
Unsafe.getUnsafe().putInt(appendPointer, value);
appendPointer += 4;
} else {
putIntBytes(value);
}
}
public void putLong(long offset, long value) {
if (roOffsetLo < offset && offset < roOffsetHi - 8) {
Unsafe.getUnsafe().putLong(absolutePointer + offset, value);
} else {
putLongBytes(offset, value);
}
}
public final void putLong(long value) {
if (pageHi - appendPointer > 7) {
Unsafe.getUnsafe().putLong(appendPointer, value);
appendPointer += 8;
} else {
putLongBytes(value);
}
}
public final void putLong128(long l1, long l2) {
if (pageHi - appendPointer > 15) {
Unsafe.getUnsafe().putLong(appendPointer, l1);
Unsafe.getUnsafe().putLong(appendPointer + Long.BYTES, l2);
appendPointer += 16;
} else {
putLong(l1);
putLong(l2);
}
}
public void putLong256(long offset, Long256 value) {
putLong256(
offset,
......@@ -420,15 +450,6 @@ public class VirtualMemory implements Closeable {
}
}
public final void putInt(int value) {
if (pageHi - appendPointer > 3) {
Unsafe.getUnsafe().putInt(appendPointer, value);
appendPointer += 4;
} else {
putIntBytes(value);
}
}
public final void putLong256(long l0, long l1, long l2, long l3) {
if (pageHi - appendPointer > Long256.BYTES - 1) {
Unsafe.getUnsafe().putLong(appendPointer, l0);
......@@ -453,23 +474,6 @@ public class VirtualMemory implements Closeable {
);
}
public void putLong(long offset, long value) {
if (roOffsetLo < offset && offset < roOffsetHi - 8) {
Unsafe.getUnsafe().putLong(absolutePointer + offset, value);
} else {
putLongBytes(offset, value);
}
}
public final void putLong(long value) {
if (pageHi - appendPointer > 7) {
Unsafe.getUnsafe().putLong(appendPointer, value);
appendPointer += 8;
} else {
putLongBytes(value);
}
}
public final void putLong256(CharSequence hexString) {
if (pageHi - appendPointer < 4 * Long.BYTES) {
putLong256Bytes(hexString);
......@@ -595,6 +599,13 @@ public class VirtualMemory implements Closeable {
}
}
private static void copyStrChars(CharSequence value, int pos, int len, long address) {
for (int i = 0; i < len; i++) {
char c = value.charAt(i + pos);
Unsafe.getUnsafe().putChar(address + 2 * i, c);
}
}
private long addressOf0(long offset) {
return computeHotPage(pageIndex(offset)) + offsetInPage(offset);
}
......
......@@ -48,6 +48,21 @@ public abstract class AbstractRedBlackTree implements Mutable, Closeable {
this.mem = new MemoryPages(keyPageSize);
}
@Override
public void clear() {
root = -1;
this.mem.clear();
}
@Override
public void close() {
Misc.free(mem);
}
public long size() {
return mem.size() / getBlockSize();
}
protected static void setLeft(long blockAddress, long left) {
Unsafe.getUnsafe().putLong(blockAddress + O_LEFT, left);
}
......@@ -110,17 +125,6 @@ public abstract class AbstractRedBlackTree implements Mutable, Closeable {
return p;
}
@Override
public void clear() {
root = -1;
this.mem.clear();
}
@Override
public void close() {
Misc.free(mem);
}
protected long allocateBlock() {
long p = mem.allocate(getBlockSize());
setLeft(p, -1);
......@@ -129,45 +133,47 @@ public abstract class AbstractRedBlackTree implements Mutable, Closeable {
return p;
}
public long size() {
return mem.size() / getBlockSize();
}
protected void fix(long x) {
setColor(x, RED);
while (x != -1 && x != root && colorOf(parentOf(x)) == RED) {
if (parentOf(x) == leftOf(parent2Of(x))) {
long y = rightOf(parent2Of(x));
long px;
while (x != -1 && x != root && colorOf(px = parentOf(x)) == RED) {
long p20x = parent2Of(x);
if (px == leftOf(p20x)) {
long y = rightOf(p20x);
if (colorOf(y) == RED) {
setColor(parentOf(x), BLACK);
setColor(px, BLACK);
setColor(y, BLACK);
setColor(parent2Of(x), RED);
x = parent2Of(x);
setColor(p20x, RED);
x = p20x;
} else {
if (x == rightOf(parentOf(x))) {
x = parentOf(x);
if (x == rightOf(px)) {
x = px;
rotateLeft(x);
px = parentOf(x);
p20x = parent2Of(x);
}
setColor(parentOf(x), BLACK);
setColor(parent2Of(x), RED);
rotateRight(parent2Of(x));
setColor(px, BLACK);
setColor(p20x, RED);
rotateRight(p20x);
}
} else {
long y = leftOf(parent2Of(x));
long y = leftOf(p20x);
if (colorOf(y) == RED) {
setColor(parentOf(x), BLACK);
setColor(px, BLACK);
setColor(y, BLACK);
setColor(parent2Of(x), RED);
x = parent2Of(x);
setColor(p20x, RED);
x = p20x;
} else {
if (x == leftOf(parentOf(x))) {
if (x == leftOf(px)) {
x = parentOf(x);
rotateRight(x);
px = parentOf(x);
p20x = parent2Of(x);
}
setColor(parentOf(x), BLACK);
setColor(parent2Of(x), RED);
rotateLeft(parent2Of(x));
setColor(px, BLACK);
setColor(p20x, RED);
rotateLeft(p20x);
}
}
}
......@@ -182,24 +188,24 @@ public abstract class AbstractRedBlackTree implements Mutable, Closeable {
root = allocateBlock();
setRef(root, value);
setParent(root, -1);
setLeft(root, -1);
setRight(root, -1);
}
private void rotateLeft(long p) {
if (p != -1) {
long r = rightOf(p);
setRight(p, leftOf(r));
if (leftOf(r) != -1) {
setParent(leftOf(r), p);
final long r = rightOf(p);
final long lr = leftOf(r);
setRight(p, lr);
if (lr != -1) {
setParent(lr, p);
}
setParent(r, parentOf(p));
if (parentOf(p) == -1) {
final long pp = parentOf(p);
setParent(r, pp);
if (pp == -1) {
root = r;
} else if (leftOf(parentOf(p)) == p) {
setLeft(parentOf(p), r);
} else if (leftOf(pp) == p) {
setLeft(pp, r);
} else {
setRight(parentOf(p), r);
setRight(pp, r);
}
setLeft(r, p);
setParent(p, r);
......@@ -208,18 +214,20 @@ public abstract class AbstractRedBlackTree implements Mutable, Closeable {
private void rotateRight(long p) {
if (p != -1) {
long l = leftOf(p);
setLeft(p, rightOf(l));
if (rightOf(l) != -1) {
setParent(rightOf(l), p);
final long l = leftOf(p);
final long rl = rightOf(l);
setLeft(p, rl);
if (rl != -1) {
setParent(rl, p);
}
setParent(l, parentOf(p));
if (parentOf(p) == -1) {
final long pp = parentOf(p);
setParent(l, pp);
if (pp == -1) {
root = l;
} else if (rightOf(parentOf(p)) == p) {
setRight(parentOf(p), l);
} else if (rightOf(pp) == p) {
setRight(pp, l);
} else {
setLeft(parentOf(p), l);
setLeft(pp, l);
}
setRight(l, p);
setParent(p, l);
......
......@@ -58,8 +58,7 @@ public class LongChain implements Closeable, Mutable {
if (parentOffset != -1) {
valueChain.putLong(parentOffset, appendOffset);
}
valueChain.putLong(-1);
valueChain.putLong(value);
valueChain.putLong128(-1, value);
return appendOffset;
}
......
......@@ -50,13 +50,10 @@ public class LongTreeChain extends AbstractRedBlackTree {
Misc.free(valueChain);
}
protected void putParent(long value) {
root = allocateBlock();
long r = appendValue(value, -1L);
setRef(root, r);
setParent(root, -1);
setLeft(root, -1);
setRight(root, -1);
private long appendValue(long value, long prevValueOffset) {
final long offset = valueChain.getAppendOffset();
valueChain.putLong128(value, prevValueOffset);
return offset;
}
public TreeCursor getCursor() {
......@@ -111,11 +108,10 @@ public class LongTreeChain extends AbstractRedBlackTree {
fix(p);
}
private long appendValue(long value, long prevValueOffset) {
final long offset = valueChain.getAppendOffset();
valueChain.putLong(value);
valueChain.putLong(prevValueOffset);
return offset;
protected void putParent(long value) {
root = allocateBlock();
setRef(root, appendValue(value, -1L));
setParent(root, -1);
}
public class TreeCursor {
......
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2019 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package io.questdb.std;
import java.io.Closeable;
public class RedBlackTree implements Mutable, Closeable {
// P(8) + L + R + C(1) + REF
private static final int BLOCK_SIZE = 8 + 8 + 8 + 1 + 8;
private static final int O_LEFT = 8;
private static final int O_RIGHT = 16;
private static final int O_COLOUR = 24;
private static final int O_REF = 25;
private static final byte RED = 1;
private static final byte BLACK = 0;
private final MemoryPages mem;
private final LongComparator comparator;
private final LongIterator cursor = new LongIterator();
private long root = -1;
public RedBlackTree(LongComparator comparator, int keyPageSize) {
this.comparator = comparator;
this.mem = new MemoryPages(keyPageSize);
}
private static void setLeft(long blockAddress, long left) {
Unsafe.getUnsafe().putLong(blockAddress + O_LEFT, left);
}
private static long rightOf(long blockAddress) {
return blockAddress == -1 ? -1 : Unsafe.getUnsafe().getLong(blockAddress + O_RIGHT);
}
private static long leftOf(long blockAddress) {
return blockAddress == -1 ? -1 : Unsafe.getUnsafe().getLong(blockAddress + O_LEFT);
}
private static void setParent(long blockAddress, long parent) {
Unsafe.getUnsafe().putLong(blockAddress, parent);
}
private static long refOf(long blockAddress) {
return blockAddress == -1 ? -1 : Unsafe.getUnsafe().getLong(blockAddress + O_REF);
}
private static void setRef(long blockAddress, long recRef) {
Unsafe.getUnsafe().putLong(blockAddress + O_REF, recRef);
}
private static void setRight(long blockAddress, long right) {
Unsafe.getUnsafe().putLong(blockAddress + O_RIGHT, right);
}
private static long parentOf(long blockAddress) {
return blockAddress == -1 ? -1 : Unsafe.getUnsafe().getLong(blockAddress);
}
private static long parent2Of(long blockAddress) {
return parentOf(parentOf(blockAddress));
}
private static void setColor(long blockAddress, byte colour) {
if (blockAddress == -1) {
return;
}
Unsafe.getUnsafe().putByte(blockAddress + O_COLOUR, colour);
}
private static byte colorOf(long blockAddress) {
return blockAddress == -1 ? BLACK : Unsafe.getUnsafe().getByte(blockAddress + O_COLOUR);
}
private static long successor(long current) {
long p = rightOf(current);
if (p != -1) {
long l;
while ((l = leftOf(p)) != -1) {
p = l;
}
} else {
p = parentOf(current);
long ch = current;
while (p != -1 && ch == rightOf(p)) {
ch = p;
p = parentOf(p);
}
}
return p;
}
public void add(long value) {
if (root == -1) {
putParent(value);
return;
}
comparator.setLeft(value);
long p = root;
long parent;
int cmp;
do {
parent = p;
long r = refOf(p);
cmp = comparator.compare(r);
if (cmp <= 0) {
p = leftOf(p);
} else {
p = rightOf(p);
}
} while (p > -1);
p = allocateBlock();
setParent(p, parent);
setRef(p, value);
if (cmp <= 0) {
setLeft(parent, p);
} else {
setRight(parent, p);
}
fix(p);
}
@Override
public void clear() {
root = -1;
this.mem.clear();
}
@Override
public void close() {
mem.close();
}
public LongComparator getComparator() {
return comparator;
}
public LongIterator iterator() {
long p = root;
if (p != -1) {
long l;
while ((l = leftOf(p)) != -1) {
p = l;
}
}
cursor.current = p;
return cursor;
}
private long allocateBlock() {
long p = mem.allocate(BLOCK_SIZE);
setLeft(p, -1);
setRight(p, -1);
setColor(p, BLACK);
return p;
}
private void fix(long x) {
setColor(x, RED);
while (x != -1 && x != root && colorOf(parentOf(x)) == RED) {
if (parentOf(x) == leftOf(parent2Of(x))) {
long y = rightOf(parent2Of(x));
if (colorOf(y) == RED) {
setColor(parentOf(x), BLACK);
setColor(y, BLACK);
setColor(parent2Of(x), RED);
x = parent2Of(x);
} else {
if (x == rightOf(parentOf(x))) {
x = parentOf(x);
rotateLeft(x);
}
setColor(parentOf(x), BLACK);
setColor(parent2Of(x), RED);
rotateRight(parent2Of(x));
}
} else {
long y = leftOf(parent2Of(x));
if (colorOf(y) == RED) {
setColor(parentOf(x), BLACK);
setColor(y, BLACK);
setColor(parent2Of(x), RED);
x = parent2Of(x);
} else {
if (x == leftOf(parentOf(x))) {
x = parentOf(x);
rotateRight(x);
}
setColor(parentOf(x), BLACK);
setColor(parent2Of(x), RED);
rotateLeft(parent2Of(x));
}
}
}
setColor(root, BLACK);
}
private void putParent(long value) {
root = allocateBlock();
setRef(root, value);
setParent(root, -1);
setLeft(root, -1);
setRight(root, -1);
}
private void rotateLeft(long p) {
if (p != -1) {
long r = rightOf(p);
setRight(p, leftOf(r));
if (leftOf(r) != -1) {
setParent(leftOf(r), p);
}
setParent(r, parentOf(p));
if (parentOf(p) == -1) {
root = r;
} else if (leftOf(parentOf(p)) == p) {
setLeft(parentOf(p), r);
} else {
setRight(parentOf(p), r);
}
setLeft(r, p);
setParent(p, r);
}
}
private void rotateRight(long p) {
if (p != -1) {
long l = leftOf(p);
setLeft(p, rightOf(l));
if (rightOf(l) != -1) {
setParent(rightOf(l), p);
}
setParent(l, parentOf(p));
if (parentOf(p) == -1) {
root = l;
} else if (rightOf(parentOf(p)) == p) {
setRight(parentOf(p), l);
} else {
setLeft(parentOf(p), l);
}
setRight(l, p);
setParent(p, l);
}
}
public interface LongComparator {
int compare(long right);
void setLeft(long left);
}
public static class LongIterator {
private long current;
public boolean hasNext() {
return current != -1;
}
public long next() {
long result = refOf(current);
current = successor(current);
return result;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册