From f983ff78582b9cfd8aecb00373a25006298fa3a7 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Fri, 30 Nov 2018 22:13:19 +0900
Subject: [PATCH] Squash consecutive packet numbers to a single
 ngtcp2_acktr_entry

---
 lib/ngtcp2_acktr.c        | 101 +++++++++++++++----
 lib/ngtcp2_acktr.h        |   8 +-
 lib/ngtcp2_conn.c         |  60 +++--------
 lib/ngtcp2_ksl.c          |  24 +++++
 lib/ngtcp2_ksl.h          |   7 ++
 tests/ngtcp2_acktr_test.c | 204 ++++++++++++++++++++++++++++----------
 tests/ngtcp2_conn_test.c  |   7 +-
 7 files changed, 285 insertions(+), 126 deletions(-)

diff --git a/lib/ngtcp2_acktr.c b/lib/ngtcp2_acktr.c
index ca793885..1486353d 100644
--- a/lib/ngtcp2_acktr.c
+++ b/lib/ngtcp2_acktr.c
@@ -37,6 +37,7 @@ int ngtcp2_acktr_entry_new(ngtcp2_acktr_entry **ent, uint64_t pkt_num,
   }
 
   (*ent)->pkt_num = pkt_num;
+  (*ent)->len = 1;
   (*ent)->tstamp = tstamp;
 
   return 0;
@@ -94,22 +95,78 @@ void ngtcp2_acktr_free(ngtcp2_acktr *acktr) {
   ngtcp2_ringbuf_free(&acktr->acks);
 }
 
-int ngtcp2_acktr_add(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent,
-                     int active_ack, ngtcp2_tstamp ts) {
+int ngtcp2_acktr_add(ngtcp2_acktr *acktr, uint64_t pkt_num, int active_ack,
+                     ngtcp2_tstamp ts) {
   ngtcp2_ksl_it it;
-  ngtcp2_acktr_entry *delent;
+  ngtcp2_acktr_entry *ent, *prev_ent, *delent;
   int rv;
+  int added = 0;
 
-  it = ngtcp2_ksl_lower_bound(&acktr->ents, (int64_t)ent->pkt_num);
-  if (!ngtcp2_ksl_it_end(&it) &&
-      ngtcp2_ksl_it_key(&it) == (int64_t)ent->pkt_num) {
-    /* TODO What to do if we receive duplicated packet number? */
-    return NGTCP2_ERR_INVALID_ARGUMENT;
+  if (ngtcp2_ksl_len(&acktr->ents)) {
+    it = ngtcp2_ksl_lower_bound(&acktr->ents, (int64_t)pkt_num);
+    if (ngtcp2_ksl_it_end(&it)) {
+      ngtcp2_ksl_it_prev(&it);
+      ent = ngtcp2_ksl_it_get(&it);
+
+      assert(ent->pkt_num >= pkt_num + ent->len);
+
+      if (ent->pkt_num == pkt_num + ent->len) {
+        ++ent->len;
+        added = 1;
+      }
+    } else {
+      ent = ngtcp2_ksl_it_get(&it);
+
+      assert(ent->pkt_num != pkt_num);
+
+      if (ngtcp2_ksl_it_begin(&it)) {
+        if (ent->pkt_num + 1 == pkt_num) {
+          ngtcp2_ksl_update_key(&acktr->ents, (int64_t)ent->pkt_num,
+                                (int64_t)pkt_num);
+          ent->pkt_num = pkt_num;
+          ++ent->len;
+          added = 1;
+        }
+      } else {
+        ngtcp2_ksl_it_prev(&it);
+        prev_ent = ngtcp2_ksl_it_get(&it);
+
+        assert(prev_ent->pkt_num >= pkt_num + prev_ent->len);
+
+        if (ent->pkt_num + 1 == pkt_num) {
+          if (prev_ent->pkt_num == pkt_num + prev_ent->len) {
+            prev_ent->len += ent->len + 1;
+            rv = ngtcp2_ksl_remove(&acktr->ents, NULL, (int64_t)ent->pkt_num);
+            if (rv != 0) {
+              return rv;
+            }
+            ngtcp2_acktr_entry_del(ent, acktr->mem);
+            added = 1;
+          } else {
+            ngtcp2_ksl_update_key(&acktr->ents, (int64_t)ent->pkt_num,
+                                  (int64_t)pkt_num);
+            ent->pkt_num = pkt_num;
+            ++ent->len;
+            added = 1;
+          }
+        } else if (prev_ent->pkt_num == pkt_num + prev_ent->len) {
+          ++prev_ent->len;
+          added = 1;
+        }
+      }
+    }
   }
 
-  rv = ngtcp2_ksl_insert(&acktr->ents, NULL, (int64_t)ent->pkt_num, ent);
-  if (rv != 0) {
-    return rv;
+  if (!added) {
+    rv = ngtcp2_acktr_entry_new(&ent, pkt_num, ts, acktr->mem);
+    if (rv != 0) {
+      return rv;
+    }
+    rv = ngtcp2_ksl_insert(&acktr->ents, NULL, (int64_t)ent->pkt_num, ent);
+    if (rv != 0) {
+      ngtcp2_acktr_entry_del(ent, acktr->mem);
+      return rv;
+    }
   }
 
   if (active_ack) {
@@ -226,9 +283,14 @@ static int acktr_on_ack(ngtcp2_acktr *acktr, ngtcp2_ringbuf *rb,
     if (ent->pkt_num < min_ack) {
       break;
     }
-    rv = acktr_remove(acktr, &it, ent);
-    if (rv != 0) {
-      return rv;
+    if (ent->pkt_num == largest_ack &&
+        ent->pkt_num - (ent->len - 1) == min_ack) {
+      rv = acktr_remove(acktr, &it, ent);
+      if (rv != 0) {
+        return rv;
+      }
+    } else {
+      ngtcp2_ksl_it_next(&it);
     }
   }
 
@@ -246,9 +308,14 @@ static int acktr_on_ack(ngtcp2_acktr *acktr, ngtcp2_ringbuf *rb,
       if (ent->pkt_num < min_ack) {
         break;
       }
-      rv = acktr_remove(acktr, &it, ent);
-      if (rv != 0) {
-        return rv;
+      if (ent->pkt_num == largest_ack &&
+          ent->pkt_num - (ent->len - 1) == min_ack) {
+        rv = acktr_remove(acktr, &it, ent);
+        if (rv != 0) {
+          return rv;
+        }
+      } else {
+        ngtcp2_ksl_it_next(&it);
       }
     }
   }
diff --git a/lib/ngtcp2_acktr.h b/lib/ngtcp2_acktr.h
index 0b7f569b..6533e579 100644
--- a/lib/ngtcp2_acktr.h
+++ b/lib/ngtcp2_acktr.h
@@ -57,6 +57,7 @@ typedef struct ngtcp2_log ngtcp2_log;
  */
 struct ngtcp2_acktr_entry {
   uint64_t pkt_num;
+  size_t len;
   ngtcp2_tstamp tstamp;
 };
 
@@ -135,7 +136,8 @@ int ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_log *log, ngtcp2_mem *mem);
 void ngtcp2_acktr_free(ngtcp2_acktr *acktr);
 
 /*
- * ngtcp2_acktr_add adds |ent|.
+ * ngtcp2_acktr_add adds packet number |pkt_num| to |acktr|.
+ * |active_ack| is nonzero if |pkt_num| is retransmittable packet.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
@@ -145,8 +147,8 @@ void ngtcp2_acktr_free(ngtcp2_acktr *acktr);
  * NGTCP2_ERR_NOMEM
  *     OUt of memory.
  */
-int ngtcp2_acktr_add(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent,
-                     int active_ack, ngtcp2_tstamp ts);
+int ngtcp2_acktr_add(ngtcp2_acktr *acktr, uint64_t pkt_num, int active_ack,
+                     ngtcp2_tstamp ts);
 
 /*
  * ngtcp2_acktr_forget removes all entries which have the packet
diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c
index 0e0c1916..7f250df0 100644
--- a/lib/ngtcp2_conn.c
+++ b/lib/ngtcp2_conn.c
@@ -513,11 +513,8 @@ static uint64_t conn_compute_ack_delay(ngtcp2_conn *conn) {
 static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
                                  ngtcp2_acktr *acktr, ngtcp2_tstamp ts,
                                  uint8_t ack_delay_exponent) {
-  uint64_t first_pkt_num;
   uint64_t last_pkt_num;
   ngtcp2_ack_blk *blk;
-  int initial = 1;
-  uint64_t gap;
   ngtcp2_ksl_it it;
   ngtcp2_acktr_entry *rpkt;
   ngtcp2_frame *fr;
@@ -550,10 +547,10 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
   ack = &fr->ack;
 
   rpkt = ngtcp2_ksl_it_get(&it);
-  first_pkt_num = last_pkt_num = rpkt->pkt_num;
-
+  last_pkt_num = rpkt->pkt_num - (rpkt->len - 1);
   ack->type = NGTCP2_FRAME_ACK;
-  ack->largest_ack = first_pkt_num;
+  ack->largest_ack = rpkt->pkt_num;
+  ack->first_ack_blklen = rpkt->len - 1;
   ack->ack_delay_unscaled = ts - rpkt->tstamp;
   ack->ack_delay = (ack->ack_delay_unscaled / 1000) >> ack_delay_exponent;
   ack->num_blks = 0;
@@ -562,38 +559,7 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
 
   for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) {
     rpkt = ngtcp2_ksl_it_get(&it);
-    if (rpkt->pkt_num + 1 == last_pkt_num) {
-      last_pkt_num = rpkt->pkt_num;
-      continue;
-    }
 
-    if (initial) {
-      initial = 0;
-      ack->first_ack_blklen = first_pkt_num - last_pkt_num;
-    } else {
-      blk_idx = ack->num_blks++;
-      rv = conn_ensure_ack_blks(conn, &fr, &num_blks_max, ack->num_blks);
-      if (rv != 0) {
-        ngtcp2_mem_free(conn->mem, fr);
-        return rv;
-      }
-      ack = &fr->ack;
-      blk = &ack->blks[blk_idx];
-      blk->gap = gap;
-      blk->blklen = first_pkt_num - last_pkt_num;
-    }
-
-    gap = last_pkt_num - rpkt->pkt_num - 2;
-    first_pkt_num = last_pkt_num = rpkt->pkt_num;
-
-    if (ack->num_blks == NGTCP2_MAX_ACK_BLKS - 1) {
-      break;
-    }
-  }
-
-  if (initial) {
-    ack->first_ack_blklen = first_pkt_num - last_pkt_num;
-  } else {
     blk_idx = ack->num_blks++;
     rv = conn_ensure_ack_blks(conn, &fr, &num_blks_max, ack->num_blks);
     if (rv != 0) {
@@ -602,8 +568,14 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr,
     }
     ack = &fr->ack;
     blk = &ack->blks[blk_idx];
-    blk->gap = gap;
-    blk->blklen = first_pkt_num - last_pkt_num;
+    blk->gap = last_pkt_num - rpkt->pkt_num - 2;
+    blk->blklen = rpkt->len - 1;
+
+    last_pkt_num = rpkt->pkt_num - (rpkt->len - 1);
+
+    if (ack->num_blks == NGTCP2_MAX_ACK_BLKS) {
+      break;
+    }
   }
 
   /* TODO Just remove entries which cannot fit into a single ACK frame
@@ -5315,17 +5287,11 @@ int ngtcp2_conn_get_handshake_completed(ngtcp2_conn *conn) {
 
 int ngtcp2_conn_sched_ack(ngtcp2_conn *conn, ngtcp2_acktr *acktr,
                           uint64_t pkt_num, int active_ack, ngtcp2_tstamp ts) {
-  ngtcp2_acktr_entry *rpkt;
   int rv;
+  (void)conn;
 
-  rv = ngtcp2_acktr_entry_new(&rpkt, pkt_num, ts, conn->mem);
-  if (rv != 0) {
-    return rv;
-  }
-
-  rv = ngtcp2_acktr_add(acktr, rpkt, active_ack, ts);
+  rv = ngtcp2_acktr_add(acktr, pkt_num, active_ack, ts);
   if (rv != 0) {
-    ngtcp2_acktr_entry_del(rpkt, conn->mem);
     /* NGTCP2_ERR_INVALID_ARGUMENT means duplicated packet number.
        Just ignore it for now. */
     if (rv != NGTCP2_ERR_INVALID_ARGUMENT) {
diff --git a/lib/ngtcp2_ksl.c b/lib/ngtcp2_ksl.c
index cf19feec..895f67c2 100644
--- a/lib/ngtcp2_ksl.c
+++ b/lib/ngtcp2_ksl.c
@@ -536,6 +536,30 @@ ngtcp2_ksl_it ngtcp2_ksl_lower_bound(ngtcp2_ksl *ksl, int64_t key) {
   }
 }
 
+void ngtcp2_ksl_update_key(ngtcp2_ksl *ksl, int64_t old_key, int64_t new_key) {
+  ngtcp2_ksl_blk *blk = ksl->head;
+  ngtcp2_ksl_node *node;
+  size_t i;
+
+  for (;;) {
+    for (i = 0, node = &blk->nodes[i]; ksl->compar(node->key, old_key);
+         ++i, node = &blk->nodes[i])
+      ;
+
+    if (blk->leaf) {
+      assert(node->key == old_key);
+      node->key = new_key;
+      return;
+    }
+
+    if (node->key == old_key) {
+      node->key = new_key;
+    }
+
+    blk = node->blk;
+  }
+}
+
 static void ksl_print(ngtcp2_ksl *ksl, const ngtcp2_ksl_blk *blk,
                       size_t level) {
   size_t i;
diff --git a/lib/ngtcp2_ksl.h b/lib/ngtcp2_ksl.h
index 9f074c97..070cb95a 100644
--- a/lib/ngtcp2_ksl.h
+++ b/lib/ngtcp2_ksl.h
@@ -179,6 +179,13 @@ int ngtcp2_ksl_remove(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it, int64_t key);
  */
 ngtcp2_ksl_it ngtcp2_ksl_lower_bound(ngtcp2_ksl *ksl, int64_t key);
 
+/*
+ * ngtcp2_ksl_update_key replaces the key of nodes which has |old_key|
+ * with |new_key|.  |new_key| must be strictly greater than the
+ * previous node and strictly smaller than the next node.
+ */
+void ngtcp2_ksl_update_key(ngtcp2_ksl *ksl, int64_t old_key, int64_t new_key);
+
 /*
  * ngtcp2_ksl_begin returns the iterator which points to the first
  * node.  If there is no node in |ksl|, it returns the iterator which
diff --git a/tests/ngtcp2_acktr_test.c b/tests/ngtcp2_acktr_test.c
index f16ef16f..1ce2ad39 100644
--- a/tests/ngtcp2_acktr_test.c
+++ b/tests/ngtcp2_acktr_test.c
@@ -30,9 +30,8 @@
 #include "ngtcp2_test_helper.h"
 
 void test_ngtcp2_acktr_add(void) {
+  const uint64_t pkt_nums[] = {1, 5, 7, 6, 2, 3};
   ngtcp2_acktr acktr;
-  ngtcp2_acktr_entry *ents[7];
-  uint64_t max_pkt_num[] = {1, 5, 7, 7, 7, 7, 7};
   ngtcp2_acktr_entry *ent;
   ngtcp2_ksl_it it;
   size_t i;
@@ -43,55 +42,151 @@ void test_ngtcp2_acktr_add(void) {
   ngtcp2_log_init(&log, NULL, NULL, 0, NULL);
   ngtcp2_acktr_init(&acktr, &log, mem);
 
-  ngtcp2_acktr_entry_new(&ents[0], 1, 1000, mem);
-  ngtcp2_acktr_entry_new(&ents[1], 5, 1001, mem);
-  ngtcp2_acktr_entry_new(&ents[2], 7, 1002, mem);
-  ngtcp2_acktr_entry_new(&ents[3], 4, 1003, mem);
-  ngtcp2_acktr_entry_new(&ents[4], 6, 1004, mem);
-  ngtcp2_acktr_entry_new(&ents[5], 2, 1005, mem);
-  ngtcp2_acktr_entry_new(&ents[6], 3, 1006, mem);
-
-  for (i = 0; i < arraylen(ents); ++i) {
-    rv = ngtcp2_acktr_add(&acktr, ents[i], 1, 999);
+  for (i = 0; i < arraylen(pkt_nums); ++i) {
+    rv = ngtcp2_acktr_add(&acktr, pkt_nums[i], 1, 999);
 
     CU_ASSERT(0 == rv);
+  }
 
-    it = ngtcp2_acktr_get(&acktr);
-    ent = ngtcp2_ksl_it_get(&it);
+  it = ngtcp2_acktr_get(&acktr);
+  ent = ngtcp2_ksl_it_get(&it);
 
-    CU_ASSERT(max_pkt_num[i] == ent->pkt_num);
-  }
+  CU_ASSERT(7 == ent->pkt_num);
+  CU_ASSERT(3 == ent->len);
 
-  for (i = 0; i < arraylen(ents); ++i) {
-    it = ngtcp2_acktr_get(&acktr);
-    ent = ngtcp2_ksl_it_get(&it);
-    ngtcp2_ksl_remove(&acktr.ents, NULL, (int64_t)ent->pkt_num);
-    ngtcp2_acktr_entry_del(ent, mem);
+  ngtcp2_ksl_it_next(&it);
+  ent = ngtcp2_ksl_it_get(&it);
 
-    it = ngtcp2_acktr_get(&acktr);
+  CU_ASSERT(3 == ent->pkt_num);
+  CU_ASSERT(3 == ent->len);
 
-    if (i != arraylen(ents) - 1) {
-      ent = ngtcp2_ksl_it_get(&it);
+  ngtcp2_ksl_it_next(&it);
 
-      CU_ASSERT(arraylen(ents) - i - 1 == ent->pkt_num);
-    } else {
-      CU_ASSERT(ngtcp2_ksl_it_end(&it));
-    }
-  }
+  CU_ASSERT(ngtcp2_ksl_it_end(&it));
+
+  ngtcp2_acktr_free(&acktr);
+
+  /* Check all conditions */
+
+  /* The lower bound returns the one beyond of the last entry.  The
+     added packet number extends the first entry. */
+  ngtcp2_acktr_init(&acktr, &log, mem);
+
+  ngtcp2_acktr_add(&acktr, 1, 1, 0);
+  ngtcp2_acktr_add(&acktr, 0, 1, 0);
+
+  CU_ASSERT(1 == ngtcp2_ksl_len(&acktr.ents));
+
+  it = ngtcp2_acktr_get(&acktr);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(1 == ent->pkt_num);
+  CU_ASSERT(2 == ent->len);
+
+  ngtcp2_acktr_free(&acktr);
+
+  /* The entry is the first one and adding a packet number extends it
+     to the forward. */
+  ngtcp2_acktr_init(&acktr, &log, mem);
+
+  ngtcp2_acktr_add(&acktr, 0, 1, 0);
+  ngtcp2_acktr_add(&acktr, 1, 1, 0);
+
+  CU_ASSERT(1 == ngtcp2_ksl_len(&acktr.ents));
+
+  it = ngtcp2_acktr_get(&acktr);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(1 == ent->pkt_num);
+  CU_ASSERT(2 == ent->len);
+
+  ngtcp2_acktr_free(&acktr);
+
+  /* The adding entry merges the existing 2 entries. */
+  ngtcp2_acktr_init(&acktr, &log, mem);
+
+  ngtcp2_acktr_add(&acktr, 0, 1, 0);
+  ngtcp2_acktr_add(&acktr, 2, 1, 0);
+  ngtcp2_acktr_add(&acktr, 3, 1, 0);
+
+  CU_ASSERT(2 == ngtcp2_ksl_len(&acktr.ents));
+
+  ngtcp2_acktr_add(&acktr, 1, 1, 0);
+
+  CU_ASSERT(1 == ngtcp2_ksl_len(&acktr.ents));
+
+  it = ngtcp2_acktr_get(&acktr);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(3 == ent->pkt_num);
+  CU_ASSERT(4 == ent->len);
 
   ngtcp2_acktr_free(&acktr);
 
-  /* Check duplicates */
+  /* The adding entry does not merge the existing 2 entries.  It
+     extends the last entry. */
   ngtcp2_acktr_init(&acktr, &log, mem);
-  ngtcp2_acktr_entry_new(&ents[0], 1, 1000, mem);
 
-  rv = ngtcp2_acktr_add(&acktr, ents[0], 1, 999);
+  ngtcp2_acktr_add(&acktr, 0, 1, 0);
+  ngtcp2_acktr_add(&acktr, 3, 1, 0);
+  ngtcp2_acktr_add(&acktr, 4, 1, 0);
 
-  CU_ASSERT(0 == rv);
+  CU_ASSERT(2 == ngtcp2_ksl_len(&acktr.ents));
 
-  rv = ngtcp2_acktr_add(&acktr, ents[0], 1, 1003);
+  ngtcp2_acktr_add(&acktr, 1, 1, 0);
 
-  CU_ASSERT(NGTCP2_ERR_INVALID_ARGUMENT == rv);
+  CU_ASSERT(2 == ngtcp2_ksl_len(&acktr.ents));
+
+  it = ngtcp2_acktr_get(&acktr);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(4 == ent->pkt_num);
+  CU_ASSERT(2 == ent->len);
+
+  ngtcp2_ksl_it_next(&it);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(1 == ent->pkt_num);
+  CU_ASSERT(2 == ent->len);
+
+  ngtcp2_acktr_free(&acktr);
+
+  /* The adding entry does not merge the existing 2 entries.  It
+     extends the first entry. */
+  ngtcp2_acktr_init(&acktr, &log, mem);
+
+  ngtcp2_acktr_add(&acktr, 0, 1, 0);
+  ngtcp2_acktr_add(&acktr, 3, 1, 0);
+  ngtcp2_acktr_add(&acktr, 4, 1, 0);
+
+  CU_ASSERT(2 == ngtcp2_ksl_len(&acktr.ents));
+
+  ngtcp2_acktr_add(&acktr, 2, 1, 0);
+
+  CU_ASSERT(2 == ngtcp2_ksl_len(&acktr.ents));
+
+  it = ngtcp2_acktr_get(&acktr);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(4 == ent->pkt_num);
+  CU_ASSERT(3 == ent->len);
+
+  ngtcp2_ksl_it_next(&it);
+  ent = ngtcp2_ksl_it_get(&it);
+
+  CU_ASSERT(0 == ent->pkt_num);
+  CU_ASSERT(1 == ent->len);
+
+  ngtcp2_acktr_free(&acktr);
+
+  /* The added packet number does not extend any entries. */
+  ngtcp2_acktr_init(&acktr, &log, mem);
+
+  ngtcp2_acktr_add(&acktr, 0, 1, 0);
+  ngtcp2_acktr_add(&acktr, 4, 1, 0);
+  ngtcp2_acktr_add(&acktr, 2, 1, 0);
+
+  CU_ASSERT(3 == ngtcp2_ksl_len(&acktr.ents));
 
   ngtcp2_acktr_free(&acktr);
 }
@@ -109,8 +204,7 @@ void test_ngtcp2_acktr_eviction(void) {
   ngtcp2_acktr_init(&acktr, &log, mem);
 
   for (i = 0; i < NGTCP2_ACKTR_MAX_ENT + extra; ++i) {
-    ngtcp2_acktr_entry_new(&ent, i, 0, mem);
-    ngtcp2_acktr_add(&acktr, ent, 1, 999 + i);
+    ngtcp2_acktr_add(&acktr, i * 2, 1, 999 + i);
   }
 
   CU_ASSERT(NGTCP2_ACKTR_MAX_ENT == ngtcp2_ksl_len(&acktr.ents));
@@ -119,7 +213,7 @@ void test_ngtcp2_acktr_eviction(void) {
        ++i, ngtcp2_ksl_it_next(&it)) {
     ent = ngtcp2_ksl_it_get(&it);
 
-    CU_ASSERT(NGTCP2_ACKTR_MAX_ENT + extra - i - 1 == ent->pkt_num);
+    CU_ASSERT((NGTCP2_ACKTR_MAX_ENT + extra - 1) * 2 - i * 2 == ent->pkt_num);
   }
 
   ngtcp2_acktr_free(&acktr);
@@ -128,8 +222,7 @@ void test_ngtcp2_acktr_eviction(void) {
   ngtcp2_acktr_init(&acktr, &log, mem);
 
   for (i = NGTCP2_ACKTR_MAX_ENT + extra; i > 0; --i) {
-    ngtcp2_acktr_entry_new(&ent, i - 1, 0, mem);
-    ngtcp2_acktr_add(&acktr, ent, 1, 999 + i);
+    ngtcp2_acktr_add(&acktr, (i - 1) * 2, 1, 999 + i);
   }
 
   CU_ASSERT(NGTCP2_ACKTR_MAX_ENT == ngtcp2_ksl_len(&acktr.ents));
@@ -138,7 +231,7 @@ void test_ngtcp2_acktr_eviction(void) {
        ++i, ngtcp2_ksl_it_next(&it)) {
     ent = ngtcp2_ksl_it_get(&it);
 
-    CU_ASSERT(NGTCP2_ACKTR_MAX_ENT + extra - i - 1 == ent->pkt_num);
+    CU_ASSERT((NGTCP2_ACKTR_MAX_ENT + extra - 1) * 2 - i * 2 == ent->pkt_num);
   }
 
   ngtcp2_acktr_free(&acktr);
@@ -156,8 +249,7 @@ void test_ngtcp2_acktr_forget(void) {
   ngtcp2_acktr_init(&acktr, &log, mem);
 
   for (i = 0; i < 7; ++i) {
-    ngtcp2_acktr_entry_new(&ent, i, 0, mem);
-    ngtcp2_acktr_add(&acktr, ent, 1, 999 + i);
+    ngtcp2_acktr_add(&acktr, i * 2, 1, 999 + i);
   }
 
   CU_ASSERT(7 == ngtcp2_ksl_len(&acktr.ents));
@@ -174,17 +266,17 @@ void test_ngtcp2_acktr_forget(void) {
   it = ngtcp2_acktr_get(&acktr);
   ent = ngtcp2_ksl_it_get(&it);
 
-  CU_ASSERT(6 == ent->pkt_num);
+  CU_ASSERT(12 == ent->pkt_num);
 
   ngtcp2_ksl_it_next(&it);
   ent = ngtcp2_ksl_it_get(&it);
 
-  CU_ASSERT(5 == ent->pkt_num);
+  CU_ASSERT(10 == ent->pkt_num);
 
   ngtcp2_ksl_it_next(&it);
   ent = ngtcp2_ksl_it_get(&it);
 
-  CU_ASSERT(4 == ent->pkt_num);
+  CU_ASSERT(8 == ent->pkt_num);
 
   it = ngtcp2_acktr_get(&acktr);
   ent = ngtcp2_ksl_it_get(&it);
@@ -204,6 +296,14 @@ void test_ngtcp2_acktr_recv_ack(void) {
   uint64_t rpkt_nums[] = {
       4500, 4499, 4497, 4496, 4494, 4493, 4491, 4490, 4488, 4487, 4483,
   };
+  /*
+     4500 4499 *
+     4497 4496
+     4494 4493
+     4491 4490
+     4488 4487 *
+     4483
+  */
   ngtcp2_acktr_entry *ent;
   uint64_t pkt_num;
   ngtcp2_ack_blk *blks;
@@ -214,8 +314,7 @@ void test_ngtcp2_acktr_recv_ack(void) {
   ngtcp2_acktr_init(&acktr, &log, mem);
 
   for (i = 0; i < arraylen(rpkt_nums); ++i) {
-    ngtcp2_acktr_entry_new(&ent, rpkt_nums[i], 1, mem);
-    ngtcp2_acktr_add(&acktr, ent, 1, 999 + i);
+    ngtcp2_acktr_add(&acktr, rpkt_nums[i], 1, 999 + i);
   }
 
   for (pkt_num = 998; pkt_num <= 999; ++pkt_num) {
@@ -245,7 +344,7 @@ void test_ngtcp2_acktr_recv_ack(void) {
   ngtcp2_acktr_recv_ack(&acktr, &ackfr, NULL, 1000000009);
 
   CU_ASSERT(0 == ngtcp2_ringbuf_len(&acktr.acks));
-  CU_ASSERT(5 == ngtcp2_ksl_len(&acktr.ents));
+  CU_ASSERT(4 == ngtcp2_ksl_len(&acktr.ents));
 
   it = ngtcp2_acktr_get(&acktr);
   ent = ngtcp2_ksl_it_get(&it);
@@ -255,17 +354,12 @@ void test_ngtcp2_acktr_recv_ack(void) {
   ngtcp2_ksl_it_next(&it);
   ent = ngtcp2_ksl_it_get(&it);
 
-  CU_ASSERT(4496 == ent->pkt_num);
-
-  ngtcp2_ksl_it_next(&it);
-  ent = ngtcp2_ksl_it_get(&it);
-
   CU_ASSERT(4494 == ent->pkt_num);
 
   ngtcp2_ksl_it_next(&it);
   ent = ngtcp2_ksl_it_get(&it);
 
-  CU_ASSERT(4490 == ent->pkt_num);
+  CU_ASSERT(4491 == ent->pkt_num);
 
   ngtcp2_ksl_it_next(&it);
   ent = ngtcp2_ksl_it_get(&it);
diff --git a/tests/ngtcp2_conn_test.c b/tests/ngtcp2_conn_test.c
index ecf5eb69..5fd54dc9 100644
--- a/tests/ngtcp2_conn_test.c
+++ b/tests/ngtcp2_conn_test.c
@@ -3100,12 +3100,11 @@ void test_ngtcp2_conn_recv_compound_pkt(void) {
   it = ngtcp2_acktr_get(&conn->in_pktns.acktr);
   ackent = ngtcp2_ksl_it_get(&it);
 
-  CU_ASSERT(ackent->pkt_num == pkt_num);
+  CU_ASSERT(pkt_num == ackent->pkt_num);
+  CU_ASSERT(2 == ackent->len);
 
   ngtcp2_ksl_it_next(&it);
-  ackent = ngtcp2_ksl_it_get(&it);
-
-  CU_ASSERT(ackent->pkt_num == pkt_num - 1);
+  ngtcp2_ksl_it_end(&it);
 
   ngtcp2_conn_del(conn);
 
-- 
GitLab