diff --git a/src/protocol/generation.cpp b/src/protocol/generation.cpp index 4bb8687..8c9bbbd 100644 --- a/src/protocol/generation.cpp +++ b/src/protocol/generation.cpp @@ -14,19 +14,27 @@ void generation_estimator::reset() { uint16_t generation_estimator::visit_packet(uint16_t packet_id) { if(this->last_packet_id >= generation_estimator::overflow_area_begin) { if(packet_id > this->last_packet_id) { + /* normal behaviour */ this->last_packet_id = packet_id; return this->last_generation; - } else { + } else if(packet_id < generation_estimator::overflow_area_end) { + /* we're within a new generation */ this->last_packet_id = packet_id; return ++this->last_generation; + } else { + /* old packet */ + return this->last_generation; } } else if(this->last_packet_id <= generation_estimator::overflow_area_end) { if(packet_id >= generation_estimator::overflow_area_begin) /* old packet */ return this->last_generation - 1; - this->last_packet_id = packet_id; + if(packet_id > this->last_packet_id) + this->last_packet_id = packet_id; return this->last_generation; } else { - this->last_packet_id = packet_id; + /* only update on newer packet id */ + if(packet_id > this->last_packet_id) + this->last_packet_id = packet_id; return this->last_generation; } } diff --git a/src/protocol/generation.h b/src/protocol/generation.h index 2391182..9db608c 100644 --- a/src/protocol/generation.h +++ b/src/protocol/generation.h @@ -16,7 +16,7 @@ namespace ts::protocol { this->last_generation = generation; } private: - constexpr static uint16_t overflow_window{1024}; + constexpr static uint16_t overflow_window{1024 * 8}; constexpr static uint16_t overflow_area_begin{0xFFFF - overflow_window}; constexpr static uint16_t overflow_area_end{overflow_window}; diff --git a/test/generationTest.cpp b/test/generationTest.cpp index 6b27198..71092fe 100644 --- a/test/generationTest.cpp +++ b/test/generationTest.cpp @@ -8,14 +8,14 @@ using namespace ts::protocol; typedef std::vector> test_vector_t; -test_vector_t generate_test_vector(size_t size, int loss) { +test_vector_t generate_test_vector(size_t size, int loss, int step = 1) { test_vector_t result{}; result.reserve(size); for(size_t i = 0; i < size; i++) { if ((rand() % 100) < loss) continue; - result.emplace_back(i & 0xFFFFU, i >> 16U); + result.emplace_back((i * step) & 0xFFFFU, (i * step) >> 16U); } return result; @@ -26,8 +26,6 @@ test_vector_t swap_elements(test_vector_t vector, int per, int max_distance) { if ((rand() % 100) < per) { //lets switch auto offset = rand() % max_distance; - if(!offset) offset = 1; - std::swap(vector[index], vector[index + offset]); } } @@ -38,13 +36,15 @@ test_vector_t swap_elements(test_vector_t vector, int per, int max_distance) { bool test_vector(const std::string_view& name, const test_vector_t& vector) { generation_estimator gen{}; - size_t last_value{0}; + size_t last_value{0}, last_gen{0}, index{0}; for(auto [id, exp] : vector) { if(auto val = gen.visit_packet(id); val != exp) { - std::cout << "[" << name << "] failed for " << id << " -> " << exp << " | " << val << ". Last value: " << last_value << "\n"; + std::cout << "[" << name << "] failed for " << id << " -> " << exp << " | " << val << ". Last value: " << last_value << " gen: " << last_gen << "\n"; return false; - } + } else + last_gen = val; last_value = id; + index++; } return true; } @@ -70,31 +70,43 @@ int main() { generation_estimator gen{}; { - test_vector("00 loss", generate_test_vector(0x3000, 0)); - test_vector("10 loss", generate_test_vector(0x3000, 10)); - test_vector("25 loss", generate_test_vector(0x3000, 25)); - test_vector("50 loss", generate_test_vector(0x3000, 50)); - test_vector("80 loss", generate_test_vector(0x3000, 80)); - test_vector("99 loss", generate_test_vector(0x3000, 99)); + test_vector("00 loss", generate_test_vector(0x30000, 0)); + test_vector("10 loss", generate_test_vector(0x30000, 10)); + test_vector("25 loss", generate_test_vector(0x30000, 25)); + test_vector("50 loss", generate_test_vector(0x30000, 50)); + test_vector("80 loss", generate_test_vector(0x30000, 80)); + test_vector("99 loss", generate_test_vector(0x30000, 99)); } { - auto base = generate_test_vector(0x3000, 0); - test_vector("swap 0:4", swap_elements(base, 0, 4)); + auto base = generate_test_vector(0x30000, 0); + test_vector("swap 30:4", swap_elements(base, 30, 4)); test_vector("swap 30:20", swap_elements(base, 30, 20)); test_vector("swap 30:1000", swap_elements(base, 30, 200)); test_vector("swap 80:1000", swap_elements(base, 80, 200)); } - gen.set_last_state(0, 0); - test_vector<6>(gen, {0, 1, 2, 4, 3, 5}, {0, 0, 0, 0, 0, 0}); + { + test_vector("1k step", swap_elements(generate_test_vector(0x30000, 0, 6), 100, 8)); - gen.set_last_state(0xFF00, 0); - test_vector<6>(gen, {0, 1, 2, 4, 3, 5}, {1, 1, 1, 1, 1, 1}); + } - gen.set_last_state(0xFF00, 0); - test_vector<6>(gen, {0, 1, 2, 0xFF00, 3, 5}, {1, 1, 1, 0, 1, 1}); + if(true) { +#if 0 + gen.set_last_state(0, 0); + test_vector<6>(gen, {0, 1, 2, 4, 3, 5}, {0, 0, 0, 0, 0, 0}); - gen.set_last_state(0xFF00, 0); - test_vector<6>(gen, {0xFFFE, 0xFFFF, 0, 1, 0xFFFC, 2}, {0, 0, 1, 1, 0, 1}); + gen.set_last_state(0xFF00, 0); + test_vector<6>(gen, {0, 1, 2, 4, 3, 5}, {1, 1, 1, 1, 1, 1}); + + gen.set_last_state(0xFF00, 0); + test_vector<6>(gen, {0, 1, 2, 0xFF00, 3, 5}, {1, 1, 1, 0, 1, 1}); + + gen.set_last_state(0xFF00, 0); + test_vector<6>(gen, {0xFFFE, 0xFFFF, 0, 1, 0xFFFC, 2}, {0, 0, 1, 1, 0, 1}); +#endif + + gen.set_last_state(0xFF00, 1); + test_vector<6>(gen, {0xFFFE, 0xFFFF, 0, 1, 0xFFFC, 2}, {1, 1, 2, 2, 1, 2}); + } } \ No newline at end of file