Skip to content

Commit

Permalink
finish scan
Browse files Browse the repository at this point in the history
  • Loading branch information
MaTianmao committed Apr 20, 2020
1 parent 53e0984 commit 0bf62ea
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 188 deletions.
50 changes: 38 additions & 12 deletions ART/N.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,9 @@ N *N::getAnyChild(const N *node) {
auto n = static_cast<const N256 *>(node);
return n->getAnyChild();
}
default: {
assert(false);
}
}
return nullptr;
}
Expand All @@ -782,8 +785,10 @@ void N::change(N *node, uint8_t key, N *val) {
n->change(key, val);
return;
}
default: {
assert(false);
}
}
return;
}

template <typename curN, typename biggerN>
Expand Down Expand Up @@ -887,6 +892,9 @@ void N::insertAndUnlock(N *node, N *parentNode, uint8_t keyParent, uint8_t key,
node->writeUnlock();
break;
}
default: {
assert(false);
}
}
}

Expand All @@ -908,10 +916,14 @@ N *N::getChild(const uint8_t k, N *node) {
auto n = static_cast<N256 *>(node);
return n->getChild(k);
}
default: {
assert(false);
}
}
return nullptr;
}

// only use in normally shutdown
void N::deleteChildren(N *node) {
if (N::isLeaf(node)) {
return;
Expand All @@ -937,8 +949,10 @@ void N::deleteChildren(N *node) {
n->deleteChildren();
return;
}
default: {
assert(false);
}
}
return;
}

template <typename curN, typename smallerN>
Expand Down Expand Up @@ -1001,6 +1015,9 @@ void N::removeAndUnlock(N *node, uint8_t key, N *parentNode, uint8_t keyParent,
needRestart);
break;
}
default: {
assert(false);
}
}
}

Expand All @@ -1023,29 +1040,29 @@ void N::setCount(uint16_t count_, uint16_t compactCount_) {
compactCount = compactCount_;
}

uint32_t N::getCount() const {
switch (this->getType()) {
// only invoked in the critical section
uint32_t N::getCount(N *node) {
switch (node->getType()) {
case NTypes::N4: {
auto n = static_cast<const N4 *>(this);
auto n = static_cast<const N4 *>(node);
return n->getCount();
}
case NTypes::N16: {
auto n = static_cast<const N16 *>(this);
auto n = static_cast<const N16 *>(node);
return n->getCount();
}
case NTypes::N48: {
auto n = static_cast<const N48 *>(this);
auto n = static_cast<const N48 *>(node);
return n->getCount();
}
case NTypes::N256: {
auto n = static_cast<const N256 *>(this);
auto n = static_cast<const N256 *>(node);
return n->getCount();
}
default: {
return 0;
}
}
return 0;
}

Prefix N::getPrefi() const { return prefix.load(); }
Expand All @@ -1063,7 +1080,6 @@ void N::setPrefix(const uint8_t *prefix, uint32_t length, bool flush) {
}
if (flush)
flush_data((void *)&(this->prefix), sizeof(Prefix));
// clflush((char *)&(this->prefix), sizeof(Prefix), false, true);
}

void N::addPrefixBefore(N *node, uint8_t key) {
Expand All @@ -1081,7 +1097,6 @@ void N::addPrefixBefore(N *node, uint8_t key) {
p.prefixCount += nodeP.prefixCount + 1;
this->prefix.store(p, std::memory_order_release);
flush_data((void *)&(this->prefix), sizeof(Prefix));
// clflush((char *)&this->prefix, sizeof(Prefix), false, true);
}

bool N::isLeaf(const N *n) {
Expand All @@ -1098,6 +1113,7 @@ Leaf *N::getLeaf(const N *n) {
(reinterpret_cast<uintptr_t>(n) & ~(1ULL << 0))));
}

// only invoke this in remove and N4
std::tuple<N *, uint8_t> N::getSecondChild(N *node, const uint8_t key) {
switch (node->getType()) {
case NTypes::N4: {
Expand All @@ -1110,6 +1126,7 @@ std::tuple<N *, uint8_t> N::getSecondChild(N *node, const uint8_t key) {
}
}

// only invoke in the shutdown normally
void N::deleteNode(N *node) {
if (N::isLeaf(node)) {
return;
Expand All @@ -1135,10 +1152,15 @@ void N::deleteNode(N *node) {
delete n;
return;
}
default: {
assert(false);
}
}
delete node;
}

// invoke in the insert
// not all nodes are in the critical secton
Leaf *N::getAnyChildTid(const N *n) {
const N *nextNode = n;

Expand All @@ -1153,8 +1175,9 @@ Leaf *N::getAnyChildTid(const N *n) {
}
}

// for range query
void N::getChildren(N *node, uint8_t start, uint8_t end,
std::tuple<uint8_t, std::atomic<N *> *> children[],
std::tuple<uint8_t, N *> children[],
uint32_t &childrenCount) {
switch (node->getType()) {
case NTypes::N4: {
Expand All @@ -1177,6 +1200,9 @@ void N::getChildren(N *node, uint8_t start, uint8_t end,
n->getChildren(start, end, children, childrenCount);
return;
}
default: {
assert(false);
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions ART/N.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class N : public BaseNode {
: BaseNode(type), level(level) {
typeVersionLockObsolete = new std::atomic<uint64_t>;
typeVersionLockObsolete->store(0b100);
old_pointer.store(0);
old_pointer.store(0, std::memory_order_seq_cst);
setType(type);
setPrefix(prefix, prefixLength, false);
}
Expand All @@ -244,7 +244,7 @@ class N : public BaseNode {
: BaseNode(type), prefix(prefi), level(level) {
typeVersionLockObsolete = new std::atomic<uint64_t>;
typeVersionLockObsolete->store(0b100);
old_pointer.store(0);
old_pointer.store(0, std::memory_order_seq_cst);
setType(type);
}

Expand Down Expand Up @@ -288,7 +288,7 @@ class N : public BaseNode {

uint32_t getLevel() const;

uint32_t getCount() const;
static uint32_t getCount(N *node);

void setCount(uint16_t count_, uint16_t compactCount_);

Expand Down Expand Up @@ -361,7 +361,7 @@ class N : public BaseNode {
uint8_t key, NTypes type, bool &needRestart);

static void getChildren(N *node, uint8_t start, uint8_t end,
std::tuple<uint8_t, std::atomic<N *> *> children[],
std::tuple<uint8_t, N *> children[],
uint32_t &childrenCount);

static void rebuild_node(N *node,
Expand Down
87 changes: 55 additions & 32 deletions ART/N16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,17 +149,16 @@ bool N16::insert(uint8_t key, N *n, bool flush) {
if (flush)
flush_data((void *)&keys[compactCount], sizeof(std::atomic<uint8_t>));


if(flush){
if (flush) {
uint64_t oldp = (1ull << 56) | ((uint64_t)compactCount << 48);
old_pointer.store(oldp); // store the old version
old_pointer.store(oldp, std::memory_order_seq_cst); // store the old version
}

children[compactCount].store(n, std::memory_order_seq_cst);

if (flush){
if (flush) {
flush_data((void *)&children[compactCount], sizeof(std::atomic<N *>));
old_pointer.store(0);
old_pointer.store(0, std::memory_order_seq_cst);
}

compactCount++;
Expand All @@ -173,12 +172,12 @@ void N16::change(uint8_t key, N *val) {

uint64_t oldp = (1ull << 56) | ((uint64_t)childPos << 48) |
((uint64_t)children[childPos].load() & ((1ull << 48) - 1));
old_pointer.store(oldp); // store the old version
old_pointer.store(oldp, std::memory_order_seq_cst); // store the old version

children[childPos].store(val, std::memory_order_seq_cst);
flush_data((void *)&children[childPos], sizeof(std::atomic<N *>));

old_pointer.store(0);
old_pointer.store(0, std::memory_order_seq_cst);
}

int N16::getChildPos(const uint8_t k) {
Expand Down Expand Up @@ -208,14 +207,13 @@ N *N16::getChild(const uint8_t k) {
N *child = children[pos].load();
if (child != nullptr && keys[pos].load() == flipSign(k)) {
uint64_t oldp = old_pointer.load();
int valid = (oldp >> 56) & 1;
int index = (oldp >> 48) & ((1 << 8) - 1);
uint8_t valid = (oldp >> 56) & 1;
uint8_t index = (oldp >> 48) & ((1 << 8) - 1);
uint64_t p = oldp & ((1ull << 48) - 1);
if(valid && pos == index){
if (valid && pos == index) {
// guarantee the p is persistent
return (N*)p;
}
else{
return (N *)p;
} else {
// guarantee child is not being modified
return child;
}
Expand All @@ -225,12 +223,12 @@ N *N16::getChild(const uint8_t k) {
// we can check from old_pointer
// weather val of key is being modified or not
uint64_t oldp = old_pointer.load();
int valid = (oldp >> 56) & 1;
int index = (oldp >> 48) & ((1 << 8) - 1);
uint8_t valid = (oldp >> 56) & 1;
uint8_t index = (oldp >> 48) & ((1 << 8) - 1);
uint64_t p = oldp & ((1ull << 48) - 1);
if(valid && keys[index].load() == k){
if (valid && keys[index].load() == k) {
// guarantee the p is persistent
return (N*)p;
return (N *)p;
}
return nullptr;
}
Expand All @@ -244,34 +242,47 @@ bool N16::remove(uint8_t k, bool force, bool flush) {

uint64_t oldp = (1ull << 56) | ((uint64_t)leafPlace << 48) |
((uint64_t)children[leafPlace].load() & ((1ull << 48) - 1));
old_pointer.store(oldp); // store the old version
old_pointer.store(oldp, std::memory_order_seq_cst); // store the old version

children[leafPlace].store(nullptr, std::memory_order_seq_cst);
flush_data((void *)&children[leafPlace], sizeof(std::atomic<N *>));

old_pointer.store(0);
old_pointer.store(0, std::memory_order_seq_cst);

count--;
assert(getChild(k) == nullptr);
return true;
}

//TODO
N *N16::getAnyChild() const {
N *anyChild = nullptr;
for (int i = 0; i < 16; ++i) {
N *child = N::clearDirty(children[i].load());
if (child != nullptr) {
if (N::isLeaf(child)) {
return child;
N *child = children[i].load();

// check old pointer
uint64_t oldp = old_pointer.load();
uint8_t valid = (oldp >> 56) & 1;
uint8_t index = (oldp >> 48) & ((1 << 8) - 1);
uint64_t p = oldp & ((1ull << 48) - 1);
if (valid && index == i) {
if ((N *)p != nullptr) {
if (N::isLeaf((N *)p)) {
return (N *)p;
}
anyChild = (N *)p;
}
} else {
if (child != nullptr) {
if (N::isLeaf(child)) {
return child;
}
anyChild = child;
}
anyChild = child;
}
}
return anyChild;
}

//TODO
void N16::deleteChildren() {
for (std::size_t i = 0; i < compactCount; ++i) {
N *child = N::clearDirty(children[i].load());
Expand All @@ -282,19 +293,31 @@ void N16::deleteChildren() {
}
}

//TODO
void N16::getChildren(uint8_t start, uint8_t end,
std::tuple<uint8_t, std::atomic<N *> *> children[],
std::tuple<uint8_t, N *> children[],
uint32_t &childrenCount) {
childrenCount = 0;
for (int i = 0; i < compactCount; ++i) {
uint8_t key = flipSign(this->keys[i].load());
if (key >= start && key <= end) {
N *child = this->children[i].load();
if (child != nullptr) {
children[childrenCount] =
std::make_tuple(key, &(this->children[i]));
childrenCount++;

// check old pointer
uint64_t oldp = old_pointer.load();
uint8_t valid = (oldp >> 56) & 1;
uint8_t index = (oldp >> 48) & ((1 << 8) - 1);
uint64_t p = oldp & ((1ull << 48) - 1);

if (valid && index == i) {
if ((N *)p != nullptr) {
children[childrenCount] = std::make_tuple(key, (N *)p);
childrenCount++;
}
} else {
if (child != nullptr) {
children[childrenCount] = std::make_tuple(key, child);
childrenCount++;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion ART/N16.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class N16 : public N {
void deleteChildren();

void getChildren(uint8_t start, uint8_t end,
std::tuple<uint8_t, std::atomic<N *> *> children[],
std::tuple<uint8_t, N *> children[],
uint32_t &childrenCount);

uint32_t getCount() const;
Expand Down
Loading

0 comments on commit 0bf62ea

Please sign in to comment.