Commit d9190c42 authored by Adam P. Goucher's avatar Adam P. Goucher

Extended pattern functionality to be streamlife-compatible

parent e7b4976f
......@@ -18,6 +18,8 @@ namespace apg {
public:
hypertree<I, 4, J, nicearray<uint64_t, 4*N>, J > htree;
using lifetree_abstract<I>::breach;
uint64_t countlayers() {
return N;
}
......@@ -159,7 +161,7 @@ namespace apg {
std::map<uint64_t, uint64_t> subleaf2int;
std::map<std::pair<I, uint32_t>, uint64_t> hnode2int;
uint64_t linenum = 0;
write_macrocell_recurse(outstream, hnode, &subleaf2int, &hnode2int, linenum);
write_macrocell_recurse(outstream, breach(hnode), &subleaf2int, &hnode2int, linenum);
}
hypernode<I> read_macrocell(std::istream &instream, std::map<uint64_t, uint64_t> *lmap, std::string &rule) {
......@@ -329,7 +331,11 @@ namespace apg {
* so as to clear the memoized population counts.
*/
if (hnode.index == 0) {
if (hnode.index2 != 0) {
return getpop_recurse(breach(hnode), modprime, layermask);
} else if (hnode.index == 0) {
// Empty nodes have population 0:
return 0;
......@@ -407,6 +413,10 @@ namespace apg {
uint64_t bound_recurse(hypernode<I> hnode, int direction, std::map<std::pair<I, uint32_t>, uint64_t> *memmap) {
if (hnode.index2 != 0) {
return bound_recurse(breach(hnode), direction, memmap);
}
uint64_t z = (direction & 2) ? 0 : (16 << hnode.depth);
auto it = memmap->find(std::make_pair(hnode.index, hnode.depth));
......@@ -562,6 +572,10 @@ namespace apg {
* Recursively copy a structure from one lifetree to another.
*/
if (hnode.index2 != 0) {
return copy_recurse(breach(hnode), lab, memmap);
}
auto it = memmap->find(std::make_pair(hnode.index, hnode.depth));
if (hnode.index == 0) {
......@@ -594,6 +608,10 @@ namespace apg {
if (N == 1) { return hnode; }
if (hnode.index2 != 0) {
return brand_recurse(breach(hnode), memmap);
}
auto it = memmap->find(std::make_pair(hnode.index, hnode.depth));
if (hnode.index == 0) {
......@@ -635,6 +653,10 @@ namespace apg {
hypernode<I> transform_recurse(hypernode<I> hnode, uint8_t perm, std::map<std::pair<I, uint32_t>, I> *memmap) {
if (hnode.index2 != 0) {
return transform_recurse(breach(hnode), perm, memmap);
}
auto it = memmap->find(std::make_pair(hnode.index, hnode.depth));
if (hnode.index == 0) {
......@@ -675,6 +697,10 @@ namespace apg {
hypernode<I> shift_recurse(hypernode<I> hnode, uint64_t x, uint64_t y, uint64_t exponent, std::map<std::pair<I, uint32_t>, I> *memmap) {
if (hnode.index2 != 0) {
return shift_recurse(breach(hnode), x, y, exponent, memmap);
}
auto it = memmap->find(std::make_pair(hnode.index, hnode.depth));
if (hnode.index == 0) {
......@@ -813,20 +839,21 @@ namespace apg {
* 3 = andn
*/
if (lnode.index == 0) {
if ((lnode.index == 0) && (lnode.index2 == 0)) {
if (operation == 0 || operation == 3) {
return lnode;
} else {
return rnode;
}
} else if (rnode.index == 0) {
} else if ((rnode.index == 0) && (rnode.index2 == 0)) {
if (operation == 0) {
return rnode;
} else {
return lnode;
}
} else if ((rnode.index2 != 0) || (lnode.index2 != 0)) {
return boolean_recurse(breach(lnode), breach(rnode), operation, memmap);
} else {
// Both operands are nonzero, so we need to actually compute
// the result recursively. Firstly, we check to see whether
// the result has already been computed and cached:
......@@ -880,6 +907,10 @@ namespace apg {
uint64_t digest_recurse(hypernode<I> hnode, std::map<std::pair<I, uint32_t>, uint64_t> *memmap) {
if (hnode.index2 != 0) {
return digest_recurse(breach(hnode), memmap);
}
auto it = memmap->find(std::make_pair(hnode.index, hnode.depth));
if (hnode.index == 0) {
return 0;
......@@ -1094,7 +1125,7 @@ namespace apg {
return str;
}
std::string _string32(hypernode<I> hnode) { return string_recurse(hnode); }
std::string _string32(hypernode<I> hnode) { return string_recurse(breach(hnode)); }
hypernode<I> _string32(std::string s) {
uint64_t loc = 0;
......@@ -1104,7 +1135,9 @@ namespace apg {
}
void bitworld_recurse(hypernode<I> hnode, bitworld* bw, uint32_t layer, int32_t x, int32_t y) {
if (hnode.index == 0) {
if (hnode.index2 != 0) {
bitworld_recurse(breach(hnode), bw, layer, x, y);
} else if (hnode.index == 0) {
return;
} else if (hnode.depth == 0) {
kiventry<nicearray<uint64_t, 4*N>, I, J >* pptr = ind2ptr_leaf(hnode.index);
......@@ -1158,6 +1191,12 @@ namespace apg {
hypernode<I> pyramid_up(hypernode<I> hnode) {
if (hnode.index2 != 0) {
hypernode<I> i1 = pyramid_up(hypernode<I>(hnode.index, hnode.depth));
hypernode<I> i2 = pyramid_up(hypernode<I>(hnode.index2, hnode.depth));
return hypernode<I>(i1.index, i2.index, i1.depth);
}
I z = 0;
if (hnode.depth == 0) {
......@@ -1181,6 +1220,15 @@ namespace apg {
hypernode<I> pyramid_down(hypernode<I> hnode) {
if (hnode.depth <= 1) { return hnode; }
if (hnode.index2 != 0) {
hypernode<I> i1 = pyramid_down(hypernode<I>(hnode.index, hnode.depth));
hypernode<I> i2 = pyramid_down(hypernode<I>(hnode.index2, hnode.depth));
while (i1.depth < i2.depth) { i1 = pyramid_up(i1); }
while (i2.depth < i1.depth) { i2 = pyramid_up(i2); }
return hypernode<I>(i1.index, i2.index, i1.depth);
}
if (hnode.index == 0) { return hypernode<I>(0, 1); }
// Extract the pointer for the node and its children:
......
......@@ -186,6 +186,18 @@ namespace apg {
return boolean_recurse(lnode, rnode, operation, &memmap);
}
hypernode<I> breach(hypernode<I> hnode) {
if (hnode.index2 == 0) {
return hnode;
} else if (hnode.index == 0) {
return hypernode<I>(hnode.index2, hnode.depth);
} else {
hypernode<I> i1(hnode.index, hnode.depth);
hypernode<I> i2(hnode.index2, hnode.depth);
return boolean_recurse(i1, i2, 1);
}
}
hypernode<I> boolean_universe(hypernode<I> lnode, hypernode<I> rnode, int operation) {
hypernode<I> lx = lnode;
hypernode<I> rx = rnode;
......
......@@ -26,7 +26,7 @@ namespace apg {
using lifetree_generic<I, N, streammeta<I> >::ninechildren;
using lifetree_generic<I, N, streammeta<I> >::fourchildren;
using lifetree_generic<I, N, streammeta<I> >::make_nonleaf;
using lifetree_abstract<I>::boolean_recurse;
using lifetree_abstract<I>::breach;
streamtree(uint64_t maxmem) {
// maxmem is specified in MiB, so we left-shift by 20:
......@@ -206,7 +206,7 @@ namespace apg {
hypernode<I> res(0, 0, hnode.depth - 1);
if (hnode.depth == 1) {
hypernode<I> hnode2 = boolean_recurse(part1, part2, 1);
hypernode<I> hnode2 = breach(hnode);
I i3 = iterate_recurse1(hnode2, mantissa, exponent, rule, history).index;
if (i3 != 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment