From b7799ddc1424362ee659830fe9d6e1736f48dc7b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 11 Jan 2023 22:55:40 -0600 Subject: [PATCH 1/2] rs: support ps > ds NVIDIA GameStream can request a minimum number of parity shards and this can sometimes exceed the number of data shards. This case is already handled properly, so there is no need to fail reed_solomon_new() if ps > ds. --- rs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs.c b/rs.c index 05f49e9..8ccb2c0 100644 --- a/rs.c +++ b/rs.c @@ -82,7 +82,7 @@ void reed_solomon_init(void) reed_solomon *reed_solomon_new(int ds, int ps) { reed_solomon *rs = NULL; - if ((ds + ps) > DATA_SHARDS_MAX || ds <= 0 || ps <= 0 || ps > ds) + if ((ds + ps) > DATA_SHARDS_MAX || ds <= 0 || ps <= 0) return NULL; rs = calloc(1, sizeof(reed_solomon) + 2 * ps * ds); if (!rs) From 40d30e1b74bda65564c6fb33016bbbcee43ebefa Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 11 Jan 2023 22:58:19 -0600 Subject: [PATCH 2/2] update tests to cover ps > ds case --- t/00util/bench.c | 16 +++++------ t/00util/test.c | 75 ++++++++++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/t/00util/bench.c b/t/00util/bench.c index dc8e835..231e9a2 100644 --- a/t/00util/bench.c +++ b/t/00util/bench.c @@ -18,9 +18,9 @@ double now(time_t epoch) } typedef reed_solomon rs_t; -void cleanup(uint8_t **buf, uint8_t **cmp, uint8_t *marks, int K) +void cleanup(uint8_t **buf, uint8_t **cmp, uint8_t *marks, int K, int N) { - for (int i = 0; i < 2 * K; i++) { + for (int i = 0; i < K + N; i++) { free(buf[i]); free(cmp[i]); } @@ -31,12 +31,12 @@ void cleanup(uint8_t **buf, uint8_t **cmp, uint8_t *marks, int K) int run(int seed, int K, int N, int T, double *et, double *dt) { - uint8_t **buf = calloc(2 * K, T * sizeof(uint8_t *)); - uint8_t **cmp = calloc(2 * K, T * sizeof(uint8_t *)); - uint8_t *marks = calloc(1, 2 * K); + uint8_t **buf = calloc(K + N, T * sizeof(uint8_t *)); + uint8_t **cmp = calloc(K + N, T * sizeof(uint8_t *)); + uint8_t *marks = calloc(1, K + N); int ret = 0; - for (int i = 0; i < 2 * K; i++) { + for (int i = 0; i < K + N; i++) { buf[i] = calloc(1, T); cmp[i] = calloc(1, T); } @@ -51,7 +51,7 @@ int run(int seed, int K, int N, int T, double *et, double *dt) reed_solomon_init(); rs_t *rs = reed_solomon_new(K, N); if (!rs) { - cleanup(buf, cmp, marks, K); + cleanup(buf, cmp, marks, K, N); printf("failed to init codec\n"); return -1; } @@ -87,7 +87,7 @@ int run(int seed, int K, int N, int T, double *et, double *dt) } assert(failed == 0); - cleanup(buf, cmp, marks, K); + cleanup(buf, cmp, marks, K, N); return ret; } diff --git a/t/00util/test.c b/t/00util/test.c index 5e5d8f3..0012ca2 100644 --- a/t/00util/test.c +++ b/t/00util/test.c @@ -14,12 +14,12 @@ typedef reed_solomon rs_t; int run(int seed, int K, int N, int T) { - uint8_t **buf = calloc(2 * K, T * sizeof(uint8_t *)); - uint8_t **cmp = calloc(2 * K, T * sizeof(uint8_t *)); - uint8_t *marks = calloc(1, 2 * K); + uint8_t **buf = calloc(K + N, T * sizeof(uint8_t *)); + uint8_t **cmp = calloc(K + N, T * sizeof(uint8_t *)); + uint8_t *marks = calloc(1, K + N); int ret = 0; - for (int i = 0; i < 2 * K; i++) { + for (int i = 0; i < K + N; i++) { buf[i] = calloc(1, T); cmp[i] = calloc(1, T); } @@ -33,40 +33,38 @@ int run(int seed, int K, int N, int T) reed_solomon_init(); rs_t *rs = reed_solomon_new(K, N); - if (!rs) { - free(buf); - free(cmp); - free(marks); - return -1; - } - reed_solomon_encode(rs, buf, K + N, T); + int failed = 0; + if (rs) { + reed_solomon_encode(rs, buf, K + N, T); - for (int i = 0; i < K + N; i++) { - marks[i] = 0; - } + for (int i = 0; i < K + N; i++) { + marks[i] = 0; + } - for (int i = 0; i < N; i++) { - int at = rand() % (K + N); - memset(buf[at], 0, T); - marks[at] = 1; - } + for (int i = 0; i < N; i++) { + int at = rand() % (K + N); + memset(buf[at], 0, T); + marks[at] = 1; + } - ret = reed_solomon_reconstruct(rs, buf, marks, K + N, T); - reed_solomon_release(rs); + ret = reed_solomon_reconstruct(rs, buf, marks, K + N, T); + reed_solomon_release(rs); - int failed = 0; - for (int i = 0; i < K; i++) { - for (int j = 0; j < T; j++) { - if (cmp[i][j] != buf[i][j]) { - printf("mismatch at row %d col %d\n", i, j); - failed = 1; - break; + for (int i = 0; i < K; i++) { + for (int j = 0; j < T; j++) { + if (cmp[i][j] != buf[i][j]) { + printf("mismatch at row %d col %d\n", i, j); + failed = 1; + break; + } } } + } else { + failed = 1; } printf("===%s===P SEED: %d K: %d N: %d T: %d\n", failed ? "FAILED" : "OK", seed, K, N, T); - for (int i = 0; i < 2 * K; i++) { + for (int i = 0; i < K + N; i++) { free(buf[i]); free(cmp[i]); } @@ -85,11 +83,20 @@ int main(int argc, char *argv[]) } srand(seed); - K = MAP(rand(), RAND_MAX, 4, 256); - N = MAP(rand(), RAND_MAX, 4, (K / 4) + 4); - if ((K + N) > 255) - K -= N; - T = MAP(rand(), RAND_MAX, 200, 1460); + K = MAP(rand(), RAND_MAX, 1, 256); + N = MAP(rand(), RAND_MAX, 1, 256); + if ((K + N) > 255) { + if (rand() % 2 == 0) { + if (N == 255) + N--; + K = 255 - N; + } else { + if (K == 255) + K--; + N = 255 - K; + } + } + T = MAP(rand(), RAND_MAX, 1, 1460); printf("===BEGIN===P SEED: %d K: %d N: %d T: %d\n", seed, K, N, T);