From 37dac22ccc806f748a5e5509c8ef78696af7c104 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 09:34:04 -0700 Subject: [PATCH 01/20] stub for new res1 test --- src/apps/testapps/testCompactCells.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 94e1d01e8..cf4269263 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -91,6 +91,14 @@ SUITE(compactCells) { free(children); } + TEST(allRes0children) { + H3Index cells0[122]; + + H3_EXPORT(getRes0Cells)(&cells0); + + t_assert(cells0[0] == 0x8001fffffffffff, "got expected parent"); + } + TEST(res0) { int hexCount = NUM_BASE_CELLS; From a094639eecbe6940bea29c7d0425f46918a7d110 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 09:34:23 -0700 Subject: [PATCH 02/20] better name --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index cf4269263..79125f07f 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -91,7 +91,7 @@ SUITE(compactCells) { free(children); } - TEST(allRes0children) { + TEST(allRes1) { H3Index cells0[122]; H3_EXPORT(getRes0Cells)(&cells0); From a618a5ee9f3ade61c1e0bc2e44550306bb6c91e2 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 09:35:32 -0700 Subject: [PATCH 03/20] formatting is happening? --- src/apps/applib/include/args.h | 4 +-- src/apps/benchmarks/benchmarkGridPathCells.c | 10 +++----- src/apps/benchmarks/benchmarkH3Api.c | 5 ++-- src/apps/benchmarks/benchmarkVertex.c | 5 ++-- src/h3lib/include/h3Index.h | 27 +++++++++++--------- 5 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/apps/applib/include/args.h b/src/apps/applib/include/args.h index 511913836..038038b03 100644 --- a/src/apps/applib/include/args.h +++ b/src/apps/applib/include/args.h @@ -90,7 +90,7 @@ int _parseArgsList(int argc, char *argv[], int numArgs, Arg *args[], // common arguments #define ARG_HELP \ - { .names = {"-h", "--help"}, .helpText = "Show this help message." } + {.names = {"-h", "--help"}, .helpText = "Show this help message."} #define DEFINE_INDEX_ARG(varName, argName) \ H3Index varName = 0; \ Arg argName = { \ @@ -109,7 +109,7 @@ int _parseArgsList(int argc, char *argv[], int numArgs, Arg *args[], .value = &varName, \ .helpText = "H3 Cell"} #define ARG_KML \ - { .names = {"-k", "--kml"}, .helpText = "Print output in KML format." } + {.names = {"-k", "--kml"}, .helpText = "Print output in KML format."} #define DEFINE_KML_NAME_ARG(varName, argName) \ char varName[BUFF_SIZE] = {0}; \ Arg argName = { \ diff --git a/src/apps/benchmarks/benchmarkGridPathCells.c b/src/apps/benchmarks/benchmarkGridPathCells.c index 2fcbaeb92..333fe967e 100644 --- a/src/apps/benchmarks/benchmarkGridPathCells.c +++ b/src/apps/benchmarks/benchmarkGridPathCells.c @@ -27,12 +27,10 @@ int64_t size; H3_EXPORT(gridPathCellsSize)(startIndex, endFar, &size); H3Index *out = calloc(size, sizeof(H3Index)); -BENCHMARK(gridPathCellsNear, 10000, { - H3_EXPORT(gridPathCells)(startIndex, endNear, out); -}); -BENCHMARK(gridPathCellsFar, 1000, { - H3_EXPORT(gridPathCells)(startIndex, endFar, out); -}); +BENCHMARK(gridPathCellsNear, 10000, + { H3_EXPORT(gridPathCells)(startIndex, endNear, out); }); +BENCHMARK(gridPathCellsFar, 1000, + { H3_EXPORT(gridPathCells)(startIndex, endFar, out); }); free(out); diff --git a/src/apps/benchmarks/benchmarkH3Api.c b/src/apps/benchmarks/benchmarkH3Api.c index d54b66597..22ec3ca8f 100644 --- a/src/apps/benchmarks/benchmarkH3Api.c +++ b/src/apps/benchmarks/benchmarkH3Api.c @@ -31,8 +31,7 @@ BENCHMARK(latLngToCell, 10000, { H3_EXPORT(latLngToCell)(&coord, 9, &h); }); BENCHMARK(cellToLatLng, 10000, { H3_EXPORT(cellToLatLng)(hex, &outCoord); }); -BENCHMARK(cellToBoundary, 10000, { - H3_EXPORT(cellToBoundary)(hex, &outBoundary); -}); +BENCHMARK(cellToBoundary, 10000, + { H3_EXPORT(cellToBoundary)(hex, &outBoundary); }); END_BENCHMARKS(); diff --git a/src/apps/benchmarks/benchmarkVertex.c b/src/apps/benchmarks/benchmarkVertex.c index a0bd6c01d..38e90cff0 100644 --- a/src/apps/benchmarks/benchmarkVertex.c +++ b/src/apps/benchmarks/benchmarkVertex.c @@ -44,9 +44,8 @@ H3Index *vertexes = calloc(6, sizeof(H3Index)); BENCHMARK(cellToVertexes, 10000, { H3_EXPORT(cellToVertexes)(hex, vertexes); }); -BENCHMARK(cellToVertexesPent, 10000, { - H3_EXPORT(cellToVertexes)(pentagon, vertexes); -}); +BENCHMARK(cellToVertexesPent, 10000, + { H3_EXPORT(cellToVertexes)(pentagon, vertexes); }); BENCHMARK(cellToVertexesRing, 10000, { for (int i = 0; i < ring2Count; i++) { diff --git a/src/h3lib/include/h3Index.h b/src/h3lib/include/h3Index.h index 6ced3c4cd..5dfa7ce3d 100644 --- a/src/h3lib/include/h3Index.h +++ b/src/h3lib/include/h3Index.h @@ -92,47 +92,50 @@ /** * Gets the highest bit of the H3 index. */ -#define H3_GET_HIGH_BIT(h3) ((int)((((h3)&H3_HIGH_BIT_MASK) >> H3_MAX_OFFSET))) +#define H3_GET_HIGH_BIT(h3) \ + ((int)((((h3) & H3_HIGH_BIT_MASK) >> H3_MAX_OFFSET))) /** * Sets the highest bit of the h3 to v. */ -#define H3_SET_HIGH_BIT(h3, v) \ - (h3) = (((h3)&H3_HIGH_BIT_MASK_NEGATIVE) | \ +#define H3_SET_HIGH_BIT(h3, v) \ + (h3) = (((h3) & H3_HIGH_BIT_MASK_NEGATIVE) | \ (((uint64_t)(v)) << H3_MAX_OFFSET)) /** * Gets the integer mode of h3. */ -#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET))) +#define H3_GET_MODE(h3) ((int)((((h3) & H3_MODE_MASK) >> H3_MODE_OFFSET))) /** * Sets the integer mode of h3 to v. */ #define H3_SET_MODE(h3, v) \ - (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET)) + (h3) = \ + (((h3) & H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET)) /** * Gets the integer base cell of h3. */ -#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET))) +#define H3_GET_BASE_CELL(h3) ((int)((((h3) & H3_BC_MASK) >> H3_BC_OFFSET))) /** * Sets the integer base cell of h3 to bc. */ #define H3_SET_BASE_CELL(h3, bc) \ - (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET)) + (h3) = (((h3) & H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET)) /** * Gets the integer resolution of h3. */ -#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET))) +#define H3_GET_RESOLUTION(h3) ((int)((((h3) & H3_RES_MASK) >> H3_RES_OFFSET))) /** * Sets the integer resolution of h3. */ #define H3_SET_RESOLUTION(h3, res) \ - (h3) = (((h3)&H3_RES_MASK_NEGATIVE) | (((uint64_t)(res)) << H3_RES_OFFSET)) + (h3) = \ + (((h3) & H3_RES_MASK_NEGATIVE) | (((uint64_t)(res)) << H3_RES_OFFSET)) /** * Gets the resolution res integer digit (0-7) of h3. @@ -145,15 +148,15 @@ * Sets a value in the reserved space. Setting to non-zero may produce invalid * indexes. */ -#define H3_SET_RESERVED_BITS(h3, v) \ - (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \ +#define H3_SET_RESERVED_BITS(h3, v) \ + (h3) = (((h3) & H3_RESERVED_MASK_NEGATIVE) | \ (((uint64_t)(v)) << H3_RESERVED_OFFSET)) /** * Gets a value in the reserved space. Should always be zero for valid indexes. */ #define H3_GET_RESERVED_BITS(h3) \ - ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET))) + ((int)((((h3) & H3_RESERVED_MASK) >> H3_RESERVED_OFFSET))) /** * Sets the resolution res digit of h3 to the integer digit (0-7) From 63a27237d61fd8408dab1f0a582397b620f5c8e1 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 10:01:42 -0700 Subject: [PATCH 04/20] clean up test for all res 1 --- src/apps/testapps/testCompactCells.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 79125f07f..9dff87729 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -92,11 +92,20 @@ SUITE(compactCells) { } TEST(allRes1) { - H3Index cells0[122]; + int64_t numRes0 = 122; + int64_t numRes1 = 842; + H3Index cells0[numRes0]; + H3Index cells1[numRes1]; H3_EXPORT(getRes0Cells)(&cells0); + t_assert(cells0[0] == 0x8001fffffffffff, "got expected first res0 cell"); - t_assert(cells0[0] == 0x8001fffffffffff, "got expected parent"); + t_assertSuccess( + H3_EXPORT(uncompactCells)(cells0, numRes0, cells1, numRes1, 1)); + + H3Index out[numRes1]; + // also dies at 41! + t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numRes1)); } TEST(res0) { From e5fa3bb182106236163fcbff7caed52931e39c36 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 10:20:44 -0700 Subject: [PATCH 05/20] failing test --- src/apps/testapps/testCompactCells.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 9dff87729..363e93926 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -98,14 +98,22 @@ SUITE(compactCells) { H3Index cells1[numRes1]; H3_EXPORT(getRes0Cells)(&cells0); - t_assert(cells0[0] == 0x8001fffffffffff, "got expected first res0 cell"); + t_assert(cells0[0] == 0x8001fffffffffff, + "got expected first res0 cell"); t_assertSuccess( H3_EXPORT(uncompactCells)(cells0, numRes0, cells1, numRes1, 1)); H3Index out[numRes1]; - // also dies at 41! - t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numRes1)); + + // Fails at compactCells. + // However: + // Passes if numUncompacted <= 40 + // Fails if numUncompacted >= 41. + int64_t numUncompacted = numRes1; + t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); + + // TODO: check that output matches cells0 } TEST(res0) { From 8f778296777a0525de3efc19c73b3102c526fa90 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 10:25:38 -0700 Subject: [PATCH 06/20] Demonstrate pass at `numUncompacted = 40` --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 363e93926..9fe3c7eec 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -110,7 +110,7 @@ SUITE(compactCells) { // However: // Passes if numUncompacted <= 40 // Fails if numUncompacted >= 41. - int64_t numUncompacted = numRes1; + int64_t numUncompacted = 40; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); // TODO: check that output matches cells0 From 944a62b04ef8420173fc56e964d6b501b07ad60d Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 10:33:34 -0700 Subject: [PATCH 07/20] retry: Demonstrate pass at `numUncompacted = 40` --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 9fe3c7eec..2887e4d8b 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -97,7 +97,7 @@ SUITE(compactCells) { H3Index cells0[numRes0]; H3Index cells1[numRes1]; - H3_EXPORT(getRes0Cells)(&cells0); + H3_EXPORT(getRes0Cells)(cells0); t_assert(cells0[0] == 0x8001fffffffffff, "got expected first res0 cell"); From 6159f5ca866a2b9c17c5784e44b44fe8190e3fea Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 10:51:30 -0700 Subject: [PATCH 08/20] should fix the formatting issue --- src/apps/applib/include/args.h | 4 +-- src/apps/benchmarks/benchmarkGridPathCells.c | 10 +++++--- src/apps/benchmarks/benchmarkH3Api.c | 5 ++-- src/apps/benchmarks/benchmarkVertex.c | 5 ++-- src/h3lib/include/h3Index.h | 27 +++++++++----------- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/apps/applib/include/args.h b/src/apps/applib/include/args.h index 038038b03..511913836 100644 --- a/src/apps/applib/include/args.h +++ b/src/apps/applib/include/args.h @@ -90,7 +90,7 @@ int _parseArgsList(int argc, char *argv[], int numArgs, Arg *args[], // common arguments #define ARG_HELP \ - {.names = {"-h", "--help"}, .helpText = "Show this help message."} + { .names = {"-h", "--help"}, .helpText = "Show this help message." } #define DEFINE_INDEX_ARG(varName, argName) \ H3Index varName = 0; \ Arg argName = { \ @@ -109,7 +109,7 @@ int _parseArgsList(int argc, char *argv[], int numArgs, Arg *args[], .value = &varName, \ .helpText = "H3 Cell"} #define ARG_KML \ - {.names = {"-k", "--kml"}, .helpText = "Print output in KML format."} + { .names = {"-k", "--kml"}, .helpText = "Print output in KML format." } #define DEFINE_KML_NAME_ARG(varName, argName) \ char varName[BUFF_SIZE] = {0}; \ Arg argName = { \ diff --git a/src/apps/benchmarks/benchmarkGridPathCells.c b/src/apps/benchmarks/benchmarkGridPathCells.c index 333fe967e..2fcbaeb92 100644 --- a/src/apps/benchmarks/benchmarkGridPathCells.c +++ b/src/apps/benchmarks/benchmarkGridPathCells.c @@ -27,10 +27,12 @@ int64_t size; H3_EXPORT(gridPathCellsSize)(startIndex, endFar, &size); H3Index *out = calloc(size, sizeof(H3Index)); -BENCHMARK(gridPathCellsNear, 10000, - { H3_EXPORT(gridPathCells)(startIndex, endNear, out); }); -BENCHMARK(gridPathCellsFar, 1000, - { H3_EXPORT(gridPathCells)(startIndex, endFar, out); }); +BENCHMARK(gridPathCellsNear, 10000, { + H3_EXPORT(gridPathCells)(startIndex, endNear, out); +}); +BENCHMARK(gridPathCellsFar, 1000, { + H3_EXPORT(gridPathCells)(startIndex, endFar, out); +}); free(out); diff --git a/src/apps/benchmarks/benchmarkH3Api.c b/src/apps/benchmarks/benchmarkH3Api.c index 22ec3ca8f..d54b66597 100644 --- a/src/apps/benchmarks/benchmarkH3Api.c +++ b/src/apps/benchmarks/benchmarkH3Api.c @@ -31,7 +31,8 @@ BENCHMARK(latLngToCell, 10000, { H3_EXPORT(latLngToCell)(&coord, 9, &h); }); BENCHMARK(cellToLatLng, 10000, { H3_EXPORT(cellToLatLng)(hex, &outCoord); }); -BENCHMARK(cellToBoundary, 10000, - { H3_EXPORT(cellToBoundary)(hex, &outBoundary); }); +BENCHMARK(cellToBoundary, 10000, { + H3_EXPORT(cellToBoundary)(hex, &outBoundary); +}); END_BENCHMARKS(); diff --git a/src/apps/benchmarks/benchmarkVertex.c b/src/apps/benchmarks/benchmarkVertex.c index 38e90cff0..a0bd6c01d 100644 --- a/src/apps/benchmarks/benchmarkVertex.c +++ b/src/apps/benchmarks/benchmarkVertex.c @@ -44,8 +44,9 @@ H3Index *vertexes = calloc(6, sizeof(H3Index)); BENCHMARK(cellToVertexes, 10000, { H3_EXPORT(cellToVertexes)(hex, vertexes); }); -BENCHMARK(cellToVertexesPent, 10000, - { H3_EXPORT(cellToVertexes)(pentagon, vertexes); }); +BENCHMARK(cellToVertexesPent, 10000, { + H3_EXPORT(cellToVertexes)(pentagon, vertexes); +}); BENCHMARK(cellToVertexesRing, 10000, { for (int i = 0; i < ring2Count; i++) { diff --git a/src/h3lib/include/h3Index.h b/src/h3lib/include/h3Index.h index 5dfa7ce3d..6ced3c4cd 100644 --- a/src/h3lib/include/h3Index.h +++ b/src/h3lib/include/h3Index.h @@ -92,50 +92,47 @@ /** * Gets the highest bit of the H3 index. */ -#define H3_GET_HIGH_BIT(h3) \ - ((int)((((h3) & H3_HIGH_BIT_MASK) >> H3_MAX_OFFSET))) +#define H3_GET_HIGH_BIT(h3) ((int)((((h3)&H3_HIGH_BIT_MASK) >> H3_MAX_OFFSET))) /** * Sets the highest bit of the h3 to v. */ -#define H3_SET_HIGH_BIT(h3, v) \ - (h3) = (((h3) & H3_HIGH_BIT_MASK_NEGATIVE) | \ +#define H3_SET_HIGH_BIT(h3, v) \ + (h3) = (((h3)&H3_HIGH_BIT_MASK_NEGATIVE) | \ (((uint64_t)(v)) << H3_MAX_OFFSET)) /** * Gets the integer mode of h3. */ -#define H3_GET_MODE(h3) ((int)((((h3) & H3_MODE_MASK) >> H3_MODE_OFFSET))) +#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET))) /** * Sets the integer mode of h3 to v. */ #define H3_SET_MODE(h3, v) \ - (h3) = \ - (((h3) & H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET)) + (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET)) /** * Gets the integer base cell of h3. */ -#define H3_GET_BASE_CELL(h3) ((int)((((h3) & H3_BC_MASK) >> H3_BC_OFFSET))) +#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET))) /** * Sets the integer base cell of h3 to bc. */ #define H3_SET_BASE_CELL(h3, bc) \ - (h3) = (((h3) & H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET)) + (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET)) /** * Gets the integer resolution of h3. */ -#define H3_GET_RESOLUTION(h3) ((int)((((h3) & H3_RES_MASK) >> H3_RES_OFFSET))) +#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET))) /** * Sets the integer resolution of h3. */ #define H3_SET_RESOLUTION(h3, res) \ - (h3) = \ - (((h3) & H3_RES_MASK_NEGATIVE) | (((uint64_t)(res)) << H3_RES_OFFSET)) + (h3) = (((h3)&H3_RES_MASK_NEGATIVE) | (((uint64_t)(res)) << H3_RES_OFFSET)) /** * Gets the resolution res integer digit (0-7) of h3. @@ -148,15 +145,15 @@ * Sets a value in the reserved space. Setting to non-zero may produce invalid * indexes. */ -#define H3_SET_RESERVED_BITS(h3, v) \ - (h3) = (((h3) & H3_RESERVED_MASK_NEGATIVE) | \ +#define H3_SET_RESERVED_BITS(h3, v) \ + (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \ (((uint64_t)(v)) << H3_RESERVED_OFFSET)) /** * Gets a value in the reserved space. Should always be zero for valid indexes. */ #define H3_GET_RESERVED_BITS(h3) \ - ((int)((((h3) & H3_RESERVED_MASK) >> H3_RESERVED_OFFSET))) + ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET))) /** * Sets the resolution res digit of h3 to the integer digit (0-7) From d811d474297d25cb86bcd47f7e36bbd9a3807cb0 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 11:14:39 -0700 Subject: [PATCH 09/20] const array sizes to fix windows errors --- src/apps/testapps/testCompactCells.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 2887e4d8b..05ea031bb 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -92,8 +92,8 @@ SUITE(compactCells) { } TEST(allRes1) { - int64_t numRes0 = 122; - int64_t numRes1 = 842; + const int64_t numRes0 = 122; + const int64_t numRes1 = 842; H3Index cells0[numRes0]; H3Index cells1[numRes1]; From d29c9b3daac76862f547517a5f3b3bc04cfac1ed Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 11:33:19 -0700 Subject: [PATCH 10/20] bah --- src/apps/testapps/testCompactCells.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 05ea031bb..192fc4fee 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -94,8 +94,9 @@ SUITE(compactCells) { TEST(allRes1) { const int64_t numRes0 = 122; const int64_t numRes1 = 842; - H3Index cells0[numRes0]; - H3Index cells1[numRes1]; + H3Index *cells0 = calloc(numRes0, sizeof(H3Index)); + H3Index *cells1 = calloc(numRes1, sizeof(H3Index)); + H3Index *out = calloc(numRes1, sizeof(H3Index)); H3_EXPORT(getRes0Cells)(cells0); t_assert(cells0[0] == 0x8001fffffffffff, @@ -104,8 +105,6 @@ SUITE(compactCells) { t_assertSuccess( H3_EXPORT(uncompactCells)(cells0, numRes0, cells1, numRes1, 1)); - H3Index out[numRes1]; - // Fails at compactCells. // However: // Passes if numUncompacted <= 40 @@ -114,6 +113,10 @@ SUITE(compactCells) { t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); // TODO: check that output matches cells0 + + free(cells0); + free(cells1); + free(out); } TEST(res0) { From fa3b1b8040c34255ab67541ea9bae5952b34d2dd Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 11:42:42 -0700 Subject: [PATCH 11/20] Demonstrate failure at numUncompacted = 41 --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 192fc4fee..b7b45f7fb 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -109,7 +109,7 @@ SUITE(compactCells) { // However: // Passes if numUncompacted <= 40 // Fails if numUncompacted >= 41. - int64_t numUncompacted = 40; + int64_t numUncompacted = 41; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); // TODO: check that output matches cells0 From e6c47e019068823c289c2597d8ec73856b5b2cc4 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 11:43:30 -0700 Subject: [PATCH 12/20] Demonstrate failure at numUncompacted = numRes1 = 842; --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index b7b45f7fb..b1ff58fea 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -109,7 +109,7 @@ SUITE(compactCells) { // However: // Passes if numUncompacted <= 40 // Fails if numUncompacted >= 41. - int64_t numUncompacted = 41; + int64_t numUncompacted = numRes1; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); // TODO: check that output matches cells0 From a3a28e61804d6082a10adfa966d40e7301c2761e Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 11:44:11 -0700 Subject: [PATCH 13/20] Demonstrate pass at numUncompacted = 40 --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index b1ff58fea..192fc4fee 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -109,7 +109,7 @@ SUITE(compactCells) { // However: // Passes if numUncompacted <= 40 // Fails if numUncompacted >= 41. - int64_t numUncompacted = numRes1; + int64_t numUncompacted = 40; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); // TODO: check that output matches cells0 From d97b939189a412fed8ea8f5d271e38cbcfb9a67c Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Thu, 26 Sep 2024 12:36:05 -0700 Subject: [PATCH 14/20] back to the full failing test demonstrating the problem --- src/apps/testapps/testCompactCells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 192fc4fee..b1ff58fea 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -109,7 +109,7 @@ SUITE(compactCells) { // However: // Passes if numUncompacted <= 40 // Fails if numUncompacted >= 41. - int64_t numUncompacted = 40; + int64_t numUncompacted = numRes1; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); // TODO: check that output matches cells0 From f199548e326d7b73626fee6a275364d066d3554b Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Sun, 29 Sep 2024 10:32:52 -0700 Subject: [PATCH 15/20] proposed fix for compact --- src/apps/testapps/testCompactCells.c | 4 +- src/h3lib/lib/h3Index.c | 68 +++++++++++++++------------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index b1ff58fea..2a56c7ae5 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -386,9 +386,7 @@ SUITE(compactCells) { 0x7, 0x400000000}; H3Index output[43] = {0}; - t_assert(H3_EXPORT(compactCells)(bad, output, numHex) == E_RES_DOMAIN, - "compactCells returns E_RES_DOMAIN on bad input (parent " - "error #2)"); + t_assertSuccess(H3_EXPORT(compactCells)(bad, output, numHex)); } TEST(uncompactCells_wrongRes) { diff --git a/src/h3lib/lib/h3Index.c b/src/h3lib/lib/h3Index.c index 193622caf..456a4c8f3 100644 --- a/src/h3lib/lib/h3Index.c +++ b/src/h3lib/lib/h3Index.c @@ -480,43 +480,49 @@ H3Error H3_EXPORT(compactCells)(const H3Index *h3Set, H3Index *compactedSet, H3Index currIndex = remainingHexes[i]; // TODO: This case is coverable (reachable by fuzzer) if (currIndex != H3_NULL) { - H3Index parent; - H3Error parentError = - H3_EXPORT(cellToParent)(currIndex, parentRes, &parent); - if (parentError) { - H3_MEMORY(free)(compactableHexes); - H3_MEMORY(free)(remainingHexes); - H3_MEMORY(free)(hashSetArray); - return parentError; - } - // Modulus hash the parent into the temp array - // to determine if this index was included in - // the compactableHexes array - int loc = (int)(parent % numRemainingHexes); - int loopCount = 0; bool isUncompactable = true; - do { - if (NEVER(loopCount > numRemainingHexes)) { - // This case should not be possible because at most one - // index is placed into hashSetArray per input hexagon. + // Resolution 0 cells always uncompactable, and trying to take + // the res -1 parent of a cell is invalid. + if (parentRes >= 0) { + H3Index parent; + H3Error parentError = + H3_EXPORT(cellToParent)(currIndex, parentRes, &parent); + if (parentError) { H3_MEMORY(free)(compactableHexes); H3_MEMORY(free)(remainingHexes); H3_MEMORY(free)(hashSetArray); - return E_FAILED; + return parentError; } - H3Index tempIndex = - hashSetArray[loc] & H3_RESERVED_MASK_NEGATIVE; - if (tempIndex == parent) { - int count = H3_GET_RESERVED_BITS(hashSetArray[loc]) + 1; - if (count == 7) { - isUncompactable = false; + // Modulus hash the parent into the temp array + // to determine if this index was included in + // the compactableHexes array + int loc = (int)(parent % numRemainingHexes); + int loopCount = 0; + do { + if (NEVER(loopCount > numRemainingHexes)) { + // This case should not be possible because at most + // one index is placed into hashSetArray per input + // hexagon. + H3_MEMORY(free)(compactableHexes); + H3_MEMORY(free)(remainingHexes); + H3_MEMORY(free)(hashSetArray); + return E_FAILED; } - break; - } else { - loc = (loc + 1) % numRemainingHexes; - } - loopCount++; - } while (hashSetArray[loc] != parent); + H3Index tempIndex = + hashSetArray[loc] & H3_RESERVED_MASK_NEGATIVE; + if (tempIndex == parent) { + int count = + H3_GET_RESERVED_BITS(hashSetArray[loc]) + 1; + if (count == 7) { + isUncompactable = false; + } + break; + } else { + loc = (loc + 1) % numRemainingHexes; + } + loopCount++; + } while (hashSetArray[loc] != parent); + } if (isUncompactable) { compactedSetOffset[uncompactableCount] = remainingHexes[i]; uncompactableCount++; From 663e02a305e8adf211ef4f0a312e43235e5570c0 Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Sun, 29 Sep 2024 10:35:25 -0700 Subject: [PATCH 16/20] test other case --- src/apps/testapps/testCompactCells.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 2a56c7ae5..c07507be7 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -15,6 +15,7 @@ */ #include +#include #include "constants.h" #include "h3Index.h" @@ -112,6 +113,18 @@ SUITE(compactCells) { int64_t numUncompacted = numRes1; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); + memset(out, 0, sizeof(H3Index) * numRes1); + + numUncompacted = 44; + t_assertSuccess( + H3_EXPORT(compactCells)(&cells1[80], out, numUncompacted)); + + memset(out, 0, sizeof(H3Index) * numRes1); + + numUncompacted = 43; + t_assertSuccess( + H3_EXPORT(compactCells)(&cells1[80], out, numUncompacted)); + // TODO: check that output matches cells0 free(cells0); From a7e07fe53f2a41c0c24a849e1c4d1b69691bda55 Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Sun, 29 Sep 2024 10:40:33 -0700 Subject: [PATCH 17/20] comprehensive test --- src/apps/testapps/testCompactCells.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index c07507be7..56ae5baee 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -113,19 +113,17 @@ SUITE(compactCells) { int64_t numUncompacted = numRes1; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); - memset(out, 0, sizeof(H3Index) * numRes1); - - numUncompacted = 44; - t_assertSuccess( - H3_EXPORT(compactCells)(&cells1[80], out, numUncompacted)); - - memset(out, 0, sizeof(H3Index) * numRes1); + // TODO: check that output matches cells0 - numUncompacted = 43; - t_assertSuccess( - H3_EXPORT(compactCells)(&cells1[80], out, numUncompacted)); + for (int64_t offset = 0; offset < numRes1; offset++) { + for (numUncompacted = numRes1 - offset; numUncompacted >= 0; + numUncompacted--) { + memset(out, 0, sizeof(H3Index) * numRes1); - // TODO: check that output matches cells0 + t_assertSuccess(H3_EXPORT(compactCells)(&cells1[offset], out, + numUncompacted)); + } + } free(cells0); free(cells1); From 6eb6ca84395e60e6882382e8ca1dd9c20ce85299 Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Sun, 29 Sep 2024 10:46:41 -0700 Subject: [PATCH 18/20] NEVER for parent error --- src/h3lib/lib/h3Index.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/h3lib/lib/h3Index.c b/src/h3lib/lib/h3Index.c index 456a4c8f3..489421e85 100644 --- a/src/h3lib/lib/h3Index.c +++ b/src/h3lib/lib/h3Index.c @@ -487,7 +487,7 @@ H3Error H3_EXPORT(compactCells)(const H3Index *h3Set, H3Index *compactedSet, H3Index parent; H3Error parentError = H3_EXPORT(cellToParent)(currIndex, parentRes, &parent); - if (parentError) { + if (NEVER(parentError)) { H3_MEMORY(free)(compactableHexes); H3_MEMORY(free)(remainingHexes); H3_MEMORY(free)(hashSetArray); From bd81be6ba62ba8ac1c7a2f4f20a6c237c59377f0 Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Mon, 30 Sep 2024 16:53:20 -0600 Subject: [PATCH 19/20] assert that all res 0 cells are found --- src/apps/testapps/testCompactCells.c | 53 ++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/apps/testapps/testCompactCells.c b/src/apps/testapps/testCompactCells.c index 56ae5baee..bab73abc2 100644 --- a/src/apps/testapps/testCompactCells.c +++ b/src/apps/testapps/testCompactCells.c @@ -106,17 +106,58 @@ SUITE(compactCells) { t_assertSuccess( H3_EXPORT(uncompactCells)(cells0, numRes0, cells1, numRes1, 1)); - // Fails at compactCells. - // However: - // Passes if numUncompacted <= 40 - // Fails if numUncompacted >= 41. int64_t numUncompacted = numRes1; t_assertSuccess(H3_EXPORT(compactCells)(cells1, out, numUncompacted)); - // TODO: check that output matches cells0 + // Assert that the output of this function matches exactly the set of + // res 0 cells + size_t foundCount = 0; + for (size_t res1Idx = 0; res1Idx < numRes1; res1Idx++) { + H3Index compactedCell = out[res1Idx]; + + if (compactedCell) { + for (size_t res1DupIdx = 0; res1DupIdx < res1Idx; + res1DupIdx++) { + t_assert(out[res1DupIdx] != compactedCell, + "Duplicated output found"); + } + + bool found = false; + for (size_t res0Idx = 0; res0Idx < numRes0; res0Idx++) { + if (cells0[res0Idx] == compactedCell) { + found = true; + break; + } + } + t_assert(found, "Res 0 cell is found"); + foundCount++; + } + } + t_assert(foundCount == numRes0, "all res 0 cells found"); + + free(cells0); + free(cells1); + free(out); + } + + TEST(allRes1_variousRanges) { + const int64_t numRes0 = 122; + const int64_t numRes1 = 842; + H3Index *cells0 = calloc(numRes0, sizeof(H3Index)); + H3Index *cells1 = calloc(numRes1, sizeof(H3Index)); + H3Index *out = calloc(numRes1, sizeof(H3Index)); + + H3_EXPORT(getRes0Cells)(cells0); + t_assert(cells0[0] == 0x8001fffffffffff, + "got expected first res0 cell"); + + t_assertSuccess( + H3_EXPORT(uncompactCells)(cells0, numRes0, cells1, numRes1, 1)); + // Test various (but not all possible combinations) ranges of res 1 + // cells for (int64_t offset = 0; offset < numRes1; offset++) { - for (numUncompacted = numRes1 - offset; numUncompacted >= 0; + for (int64_t numUncompacted = numRes1 - offset; numUncompacted >= 0; numUncompacted--) { memset(out, 0, sizeof(H3Index) * numRes1); From 25eecc5d86b78ac14c226047b3e9e9434d93d721 Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Tue, 1 Oct 2024 07:56:45 -0600 Subject: [PATCH 20/20] CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d29dd51d9..d60ee4241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The public API of this library consists of the functions declared in file [h3api.h.in](./src/h3lib/include/h3api.h.in). ## [Unreleased] +### Fixed +- Fixed compacting all or many resolution 1 cells (#919) + ### Changed - Replace internal algorithm for `polygonToCells` with a new version that is more memory-efficient (#785) - Reorganize tests into public / internal. (#762)