Skip to content

Commit dda3338

Browse files
add rx_fragment_tree_update_covered_prefix
1 parent 5b3dc61 commit dda3338

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

libudpard/udpard.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ static udpard_udpip_ep_t make_topic_ep(const uint32_t subject_id)
7373
}
7474

7575
static size_t smaller(const size_t a, const size_t b) { return (a < b) ? a : b; }
76+
static size_t smaller3(const size_t a, const size_t b, const size_t c) { return smaller(smaller(a, b), c); }
7677
static size_t larger(const size_t a, const size_t b) { return (a > b) ? a : b; }
7778
static uint32_t max_u32(const uint32_t a, const uint32_t b) { return (a > b) ? a : b; }
7879

@@ -775,15 +776,36 @@ static bool rx_fragment_tree_has_gap_in_range(udpard_tree_t* const root, const s
775776
/// True if the specified fragment should be retained. Otherwise, it is redundant and should be discarded.
776777
/// The complexity is O(log n + k), see rx_fragment_tree_has_gap_in_range() for details.
777778
static bool rx_fragment_is_needed(udpard_tree_t* const root,
778-
const size_t fragment_offset,
779-
const size_t fragment_size,
779+
const size_t frag_offset,
780+
const size_t frag_size,
780781
const size_t transfer_size,
781782
const size_t extent)
782783
{
783-
const size_t size = smaller(transfer_size, extent);
784-
const size_t left = fragment_offset;
785-
const size_t right = smaller(fragment_offset + fragment_size, size);
786-
return (left < size) && rx_fragment_tree_has_gap_in_range(root, left, right);
784+
const size_t end = smaller3(frag_offset + frag_size, transfer_size, extent);
785+
return (frag_offset < extent) && rx_fragment_tree_has_gap_in_range(root, frag_offset, end);
786+
}
787+
788+
/// Finds the number of contiguous payload bytes received from offset zero after accepting a new fragment.
789+
/// The transfer is considered fully received when covered_prefix >= min(extent, transfer_payload_size).
790+
/// This should be invoked after the fragment tree accepted a new fragment at frag_offset with frag_size.
791+
/// The complexity is linear in the number of contiguous fragments following old_prefix.
792+
static size_t rx_fragment_tree_update_covered_prefix(udpard_tree_t* const root,
793+
const size_t old_prefix,
794+
const size_t frag_offset,
795+
const size_t frag_size)
796+
{
797+
const size_t end = frag_offset + frag_size;
798+
if ((frag_offset > old_prefix) || (end <= old_prefix)) {
799+
return old_prefix; // The new fragment does not cross the frontier, so it cannot affect the prefix.
800+
}
801+
udpard_fragment_t* fr = (udpard_fragment_t*)cavl2_predecessor(root, &old_prefix, &rx_cavl_compare_fragment_offset);
802+
UDPARD_ASSERT(fr != NULL);
803+
size_t out = old_prefix;
804+
while ((fr != NULL) && (fr->offset <= out)) {
805+
out = larger(out, fr->offset + fr->view.size);
806+
fr = (udpard_fragment_t*)cavl2_next_greater(&fr->index_offset);
807+
}
808+
return out;
787809
}
788810

789811
typedef enum

0 commit comments

Comments
 (0)