int main(int argc, char **argv) { etree_t *ep; etree_addr_t root; payload_t payload; int count; char *filename; if (argc != 2) { fprintf(stderr, "Usage: %s etree\n", argv[0]); exit(0); } filename = argv[1]; /* Create an empty 3d etree with an integer record */ ep = etree_open(filename, O_RDWR|O_CREAT|O_TRUNC, 1, sizeof(payload_t), 3); if (ep == NULL) { fprintf(stderr, "Could not open etree file %s\n", filename); exit(1); } /* Register the schema for the etree to make it portable */ if (etree_registerschema(ep, "int32_t val; char tag;") != 0) { fprintf(stderr, "%s\n", etree_strerror(etree_errno(ep))); exit(1); } /* Initialize the tree with a single root octant */ /* $begin refineinit */ root.x = root.y = root.z = 0; root.level = ETREE_MAXLEVEL - 2; root.type = ETREE_LEAF; payload.tag = 'A'; payload.val = 0; if (etree_insert(ep, root, &payload) != 0) { fprintf(stderr, "%s", etree_strerror(etree_errno(ep))); exit(1); } /* $end refineinit */ /* Recursively refine the root octant */ /* $begin callrefine */ refine(ep, root); count = traverse(ep); fprintf(stderr, "The tree has %d octants\n", count); /* $end callrefine */ /* Clean up */ etree_close(ep); exit(0); }
/* $begin refine */ void refine(etree_t *ep, etree_addr_t root) { int i, j, k, incr; etree_addr_t child; static int val = 0; payload_t payload; /* $end refine */ /* The root must be a leaf node */ if (root.type != ETREE_LEAF) { fprintf(stderr, "Tried to refine an interior node\n"); exit(1); } /* $begin refine */ /* Check the terminating conditions for the recursion */ if ((root.level >= ETREE_MAXLEVEL) || (!refine_pred(root, val))) return; /* Make the root an interior node */ if (etree_delete(ep, root) != 0) { fprintf(stderr, "%s\n", etree_strerror(etree_errno(ep))); exit(1); } root.type = ETREE_INTERIOR; payload.val = val; payload.tag = 'A' + (root.level - (ETREE_MAXLEVEL - 2)); etree_insert(ep, root, &payload); /* Edge of octant at level (ETREE_MAXLEVEL-k) is 2^k ticks */ child.level = root.level + 1; child.type = ETREE_LEAF; incr = 1 << (ETREE_MAXLEVEL - child.level); /* Recursively expand the children in z-order */ for (k = 0; k <= incr; k += incr) { child.z = root.z + k; for (j = 0; j <= incr; j += incr) { child.y = root.y + j; for (i = 0; i <= incr; i += incr) { child.x = root.x + i; payload.val = ++val; payload.tag = 'A' + (child.level - (ETREE_MAXLEVEL - 2)); etree_insert(ep, child, &payload); refine(ep, child); } } } return; }
int main(int argc, char **argv) { etree_t *ep; etree_addr_t addr, res_addr; value_t res_val; char buf[ETREE_MAXBUF]; /* $end query */ if (argc != 2) { fprintf(stderr, "usage: %s etree\n", argv[0]); exit(0); } /* $begin query */ /* Open the etree for reading */ ep = etree_open(argv[1], O_RDONLY, 0, sizeof(value_t), 3); if (ep == NULL) { fprintf(stderr, "Could not open etree file %s\n", argv[1]); exit(1); } /* Query each octant specified on stdin */ printf("Input (x y z t): "); addr.level = ETREE_MAXLEVEL; while (fgets(buf, ETREE_MAXBUF, stdin)) { sscanf(buf, "%u %u %u %u", &addr.x, &addr.y, &addr.z, &addr.t); /* $end query */ /* Ignore comment or blank lines */ if ((buf[0] == '#') || (buf[0] == '\n') || (buf[0] == '\t')) { continue; } /* $begin query */ if (etree_search(ep, addr, &res_addr, &res_val) != 0) { fprintf(stderr, "%s\n", etree_strerror(etree_errno(ep))); printf("Input (x y z t): "); continue; } printf("Output (x y z t): %s = %f %f %f\n\n", etree_straddr(ep, buf, res_addr), res_val.Vx, res_val.Vy, res_val.Vz); printf("Input (x y z t): "); } etree_close(ep); exit(0); }
/** * mesh_query: * * - return 0 if OK, -1 on error * */ int mesh_query(etree_t *ep, double east_m, double north_m, double depth_m, const char *field, void *payload) { double tickSize; etree_addr_t queryAddr; /* new factor of 2 at the end... who knows why but works */ tickSize = 600000.0 / ( 2147483648.0 / 2 ); queryAddr.y = (etree_tick_t)(east_m / tickSize); queryAddr.x = (etree_tick_t)(north_m / tickSize); queryAddr.z = (etree_tick_t)(depth_m / tickSize); queryAddr.level = ETREE_MAXLEVEL; if (etree_search(ep, queryAddr, NULL, field, payload) != 0) { fprintf(stderr, "mesh_query: %s\n",etree_strerror(etree_errno(ep))); return -1; } return 0; }