use formula for aux vector
authorGeoffrey Allott <geoffrey@allott.email>
Wed, 24 Aug 2022 19:07:52 +0000 (20:07 +0100)
committerGeoffrey Allott <geoffrey@allott.email>
Wed, 24 Aug 2022 19:07:52 +0000 (20:07 +0100)
src/stree.c
test/test_stree.c

index 6995689519f00cbf368e83170eeadefa15365a13..5b68bfedf61e2f01f3841f889998f8973e165f97 100644 (file)
@@ -141,6 +141,18 @@ static size_t stree_max_size(size_t len)
     return len * 2 + 1;
 }
 
+static uint8_t stree_aux(size_t rem)
+{
+    if (rem == 0) return 0;
+    if (rem <= 1) return 1;
+    if (rem <= 2) return 2;
+    if (rem <= 4) return 3;
+    if (rem <= 8) return 4;
+    if (rem <= 16) return 5;
+    if (rem <= 32) return 6;
+    return 7;
+}
+
 int stree_encode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux)
 {
     struct node *nodes;
@@ -167,7 +179,7 @@ int stree_encode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux)
     active_node = root;
 
     for (i = 0; i < len; ++i) {
-        aux[i] = (size_t) (active_node - root);
+        aux[i] = stree_aux(rem);
         prev = (struct node *) 0;
         ++rem;
         memset(seen, 0, sizeof seen);
@@ -255,7 +267,7 @@ int stree_decode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux)
     active_node = root;
 
     for (i = 0; i < len; ++i) {
-        aux[i] = (size_t) (active_node - root);
+        aux[i] = stree_aux(rem);
         prev = (struct node *) 0;
         ++rem;
         memset(seen, 0, sizeof seen);
index e47347ee1d9c7e4528ee65b9fadbffc980ff1575..9047cd6b851742afe1cfc0409f79e49aa2272c01 100644 (file)
@@ -36,19 +36,11 @@ static enum test_result test_stree_encode_nontrivial(void)
     size_t aux[5];
     ASSERT_EQ(0, stree_encode(5, in, out, aux));
 
-    /*
-    ASSERT_EQ(0, out[0]);
-    ASSERT_EQ(1, out[1]);
-    ASSERT_EQ(0, out[2]);
+    ASSERT_EQ('a', out[0]);
+    ASSERT_EQ('b', out[1]);
+    ASSERT_EQ(1, out[2]);
     ASSERT_EQ(1, out[3]);
-    ASSERT_EQ(0, out[4]);
-    */
-
-    ASSERT_EQ(0, aux[0]);
-    ASSERT_EQ(0, aux[1]);
-    ASSERT_EQ(0, aux[2]);
-    ASSERT_EQ(0, aux[3]);
-    ASSERT_EQ(3, aux[4]);
+    ASSERT_EQ(1, out[4]);
 
     return TEST_SUCCESS;
 }
@@ -60,29 +52,16 @@ static enum test_result test_stree_encode_so_example(void)
     size_t aux[10];
     ASSERT_EQ(0, stree_encode(10, in, out, aux));
 
-    /*
-    ASSERT_EQ(0, out[0]);
-    ASSERT_EQ(1, out[1]);
-    ASSERT_EQ(2, out[2]);
-    ASSERT_EQ(0, out[3]);
+    ASSERT_EQ('a', out[0]);
+    ASSERT_EQ('b', out[1]);
+    ASSERT_EQ('c', out[2]);
+    ASSERT_EQ(2, out[3]);
     ASSERT_EQ(0, out[4]);
-    ASSERT_EQ(3, out[5]);
-    ASSERT_EQ(0, out[6]);
+    ASSERT_EQ('x', out[5]);
+    ASSERT_EQ(3, out[6]);
     ASSERT_EQ(0, out[7]);
-    ASSERT_EQ(1, out[8]);
-    ASSERT_EQ(3, out[9]);
-    */
-
-    ASSERT_EQ(0, aux[0]);
-    ASSERT_EQ(0, aux[1]);
-    ASSERT_EQ(0, aux[2]);
-    ASSERT_EQ(0, aux[3]);
-    ASSERT_EQ(0, aux[4]);
-    ASSERT_EQ(0, aux[5]);
-    ASSERT_EQ(0, aux[6]);
-    ASSERT_EQ(0, aux[7]);
-    ASSERT_EQ(4, aux[8]);
-    ASSERT_EQ(4, aux[9]);
+    ASSERT_EQ(0, out[8]);
+    ASSERT_EQ('e', out[9]);
 
     return TEST_SUCCESS;
 }
@@ -94,23 +73,13 @@ static enum test_result test_stree_tricky_suffix_link(void)
     size_t aux[7];
     ASSERT_EQ(0, stree_encode(7, in, out, aux));
 
-    /*
-    ASSERT_EQ(2, out[0]);
-    ASSERT_EQ(3, out[1]);
-    ASSERT_EQ(1, out[2]);
+    ASSERT_EQ('c', out[0]);
+    ASSERT_EQ('d', out[1]);
+    ASSERT_EQ(0, out[2]);
     ASSERT_EQ(0, out[3]);
     ASSERT_EQ(1, out[4]);
     ASSERT_EQ(0, out[5]);
     ASSERT_EQ(1, out[6]);
-    */
-
-    ASSERT_EQ(0, aux[0]);
-    ASSERT_EQ(0, aux[1]);
-    ASSERT_EQ(0, aux[2]);
-    ASSERT_EQ(0, aux[3]);
-    ASSERT_EQ(0, aux[4]);
-    ASSERT_EQ(0, aux[5]);
-    ASSERT_EQ(0, aux[6]);
 
     return TEST_SUCCESS;
 }
@@ -1326,12 +1295,6 @@ static enum test_result test_stree_decode_nontrivial(void)
     ASSERT_EQ('a', out[3]);
     ASSERT_EQ('a', out[4]);
 
-    ASSERT_EQ(0, aux[0]);
-    ASSERT_EQ(0, aux[1]);
-    ASSERT_EQ(0, aux[2]);
-    ASSERT_EQ(0, aux[3]);
-    ASSERT_EQ(3, aux[4]);
-
     return TEST_SUCCESS;
 }
 
@@ -1370,6 +1333,54 @@ static enum test_result test_stree_roundtrip_so_example(void)
     return TEST_SUCCESS;
 }
 
+static enum test_result test_stree_roundtrip_iterated(void)
+{
+    const uint8_t *in = (const uint8_t *) "1231313223";
+    uint8_t enc[10];
+    uint8_t dec[10];
+    size_t aux1[10];
+    size_t aux2[10];
+    size_t i;
+
+    ASSERT_EQ(0, stree_encode(10, in, enc, aux1));
+
+    for (i = 0; i < 1024; ++i) {
+        ASSERT_EQ(0, stree_encode(10, enc, dec, aux2));
+        ASSERT_EQ(0, stree_encode(10, dec, enc, aux2));
+    }
+
+    for (i = 0; i < 1024; ++i) {
+        ASSERT_EQ(0, stree_decode(10, enc, dec, aux2));
+        ASSERT_EQ(0, stree_decode(10, dec, enc, aux2));
+    }
+
+    ASSERT_EQ(0, stree_decode(10, enc, dec, aux2));
+
+    ASSERT_EQ(in[0], dec[0]);
+    ASSERT_EQ(in[1], dec[1]);
+    ASSERT_EQ(in[2], dec[2]);
+    ASSERT_EQ(in[3], dec[3]);
+    ASSERT_EQ(in[4], dec[4]);
+    ASSERT_EQ(in[5], dec[5]);
+    ASSERT_EQ(in[6], dec[6]);
+    ASSERT_EQ(in[7], dec[7]);
+    ASSERT_EQ(in[8], dec[8]);
+    ASSERT_EQ(in[9], dec[9]);
+
+    ASSERT_EQ(aux1[0], aux2[0]);
+    ASSERT_EQ(aux1[1], aux2[1]);
+    ASSERT_EQ(aux1[2], aux2[2]);
+    ASSERT_EQ(aux1[3], aux2[3]);
+    ASSERT_EQ(aux1[4], aux2[4]);
+    ASSERT_EQ(aux1[5], aux2[5]);
+    ASSERT_EQ(aux1[6], aux2[6]);
+    ASSERT_EQ(aux1[7], aux2[7]);
+    ASSERT_EQ(aux1[8], aux2[8]);
+    ASSERT_EQ(aux1[9], aux2[9]);
+
+    return TEST_SUCCESS;
+}
+
 int main(void)
 {
     RUN_TEST(test_stree_encode_empty);
@@ -1390,4 +1401,5 @@ int main(void)
     RUN_TEST(test_stree_decode_simple);
     RUN_TEST(test_stree_decode_nontrivial);
     RUN_TEST(test_stree_roundtrip_so_example);
+    RUN_TEST(test_stree_roundtrip_iterated);
 }