Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the new fullroots methods #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions index.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
namespace Hyper {
namespace Core {
namespace FlatTree {
size_t T0 = 0;
size_t T1 = 1;
size_t T2 = 2;
size_t T30 = 30;
size_t T31 = 30;
size_t constexpr T0 = 0;
size_t constexpr T1 = 1;
size_t constexpr T2 = 2;
size_t constexpr T30 = 30;
size_t constexpr T31 = 31;

auto rightShift (size_t n) {
return (n - (n & T1)) / T2;
Expand All @@ -30,7 +30,7 @@ namespace Hyper {
}

auto twoPow (size_t n) {
if (n < T30) {
if (n < T31) {
return T1 << n;
} else {
return ((T1 << T30) * (T1 << (n - T30)));
Expand Down Expand Up @@ -168,7 +168,7 @@ namespace Hyper {

auto parent (size_t index, size_t depth) {
auto offset = FlatTree::offset(index, depth);
return FlatTree::index(depth + T1, FlatTree::offset(offset) >> T1);
return FlatTree::index(depth + T1, rightShift(offset));
}

auto parent (size_t index) {
Expand Down Expand Up @@ -339,6 +339,37 @@ namespace Hyper {
this->offset = T2 * this->offset + T1;
return this->index;
}

size_t nextTree () {
this->index = this->index + this->factor / T2 + T1;
this->offset = this->index / T2;
this->factor = T2;
return this->index;
}

size_t prevTree () {
if (!static_cast<bool>(this->offset)) {
this->index = 0;
this->factor = 2;
} else {
this->index = this->index - this->factor / T2 - T1;
this->offset = this->index / T2;
this->factor = T2;
}
return this->index;
}

size_t fullRoot (size_t index) {
if (index <= this->index || (this->index & 1) > T0) {
return false;
}
while (index > this->index + this->factor + this->factor / 2) {
this->index += this->factor / 2;
this->factor *= 2;
this->offset /= 2;
}
return true;
}
};
} // namespace FlatTree
} // namespace Core
Expand Down
58 changes: 49 additions & 9 deletions test/index.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <iostream>
#include <vector>
#include <string>
#include <random>

#define ASSERT(message, ...) do { \
if(!(__VA_ARGS__)) { \
Expand All @@ -18,13 +19,12 @@
int main() {
namespace FlatTree = Hyper::Core::FlatTree;

int plan = 81;
int plan = 111;
int count = 0;

ASSERT("base blocks 0", FlatTree::index(0, 0) == 0)
ASSERT("base blocks 2", FlatTree::index(0, 1) == 2)
ASSERT("base blocks 4", FlatTree::index(0, 2) == 4)
ASSERT("base blocks 4", FlatTree::index(0, 2) == 4)

ASSERT("parents 1", FlatTree::index(1, 0) == 1)
ASSERT("parents 5", FlatTree::index(1, 1) == 5)
Expand Down Expand Up @@ -136,13 +136,53 @@ int main() {
{
FlatTree::Iterator it(1);

ASSERT("iterator index == 1", it.index == 1)
ASSERT("iterator parent() == 3", it.parent() == 3)
ASSERT("iterator parent() == 7", it.parent() == 7)
ASSERT("iterator rightChild() == 11", it.rightChild() == 11)
ASSERT("iterator leftChild == 9", it.leftChild() == 9)
ASSERT("iterator next() == 13", it.next() == 13)
ASSERT("iterator leftSpan() == 12", it.leftSpan() == 12)
ASSERT("nonleaf index == 1", it.index == 1)
ASSERT("nonleaf parent() == 3", it.parent() == 3)
ASSERT("nonleaf parent() == 7", it.parent() == 7)
ASSERT("nonleaf rightChild() == 11", it.rightChild() == 11)
ASSERT("nonleaf leftChild == 9", it.leftChild() == 9)
ASSERT("nonleaf next() == 13", it.next() == 13)
ASSERT("nonleaf leftSpan() == 12", it.leftSpan() == 12)
}

{
FlatTree::Iterator it(0);

ASSERT("iterator fullRoot(0) == false", it.fullRoot(0) == false)

ASSERT("iterator fullRoot(22) == true", it.fullRoot(22) == true)
ASSERT("iterator index == 7", it.index == 7)

ASSERT("iterator nextTree() == 16", it.nextTree() == 16)

ASSERT("iterator fullRoot(22) == true", it.fullRoot(22) == true)
ASSERT("iterator index == 17", it.index == 17)

ASSERT("iterator nextTree() == 20", it.nextTree() == 20)

ASSERT("iterator fullRoot(22) == true", it.fullRoot(22) == true)
ASSERT("iterator index == 20", it.index == 20)

ASSERT("iterator nextTree() == 22", it.nextTree() == 22)
ASSERT("iterator.fullRoot(22) == false", it.fullRoot(22) == false)
}

{
std::random_device randdev;
std::mt19937 randgen(randdev());
for (int i = 0; i < 10; i++) {
FlatTree::Iterator it(0);
size_t tree = static_cast<size_t>(std::generate_canonical<double, 32>(randgen) * 0xffffffff) * 2;
std::vector<size_t> expected = FlatTree::fullRoots(tree);
std::vector<size_t> actual;

for (; it.fullRoot(tree); it.nextTree()) {
actual.push_back(it.index);
}

ASSERT("big full root " << i << " actual == expected", actual == expected);
ASSERT("big full root " << i << " fullRoot(tree) == false", it.fullRoot(tree) == false);
}
}

ASSERT("PLAN == COUNT", plan == count)
Expand Down