more bug fixes

This commit is contained in:
Green Sky 2022-12-17 02:50:37 +01:00
parent 5cba374d2b
commit 03cb852bad
No known key found for this signature in database
3 changed files with 125 additions and 7 deletions

View File

@ -147,8 +147,13 @@ struct TextDocument {
std::vector<Op> ops; std::vector<Op> ops;
for (size_t i = first_idx; i < last_idx; i++) { for (size_t i = first_idx; i < last_idx; i++) {
if (!state.list.at(i).value.has_value()) {
// allready deleted
continue;
}
ops.emplace_back(typename ListType::OpDel{ ops.emplace_back(typename ListType::OpDel{
state.list[i].id state.list.at(i).id
}); });
// TODO: do delets get a seq????? // TODO: do delets get a seq?????
@ -163,7 +168,7 @@ struct TextDocument {
// note: rn it only creates 1 diff patch // note: rn it only creates 1 diff patch
std::vector<Op> merge(std::string_view text) { std::vector<Op> merge(std::string_view text) {
if (text.empty()) { if (text.empty()) {
if (state.list.empty()) { if (state.list.empty() || state.doc_size == 0) {
// no op // no op
return {}; return {};
} else { } else {
@ -185,6 +190,7 @@ struct TextDocument {
// find start and end of changes // find start and end of changes
// start // start
size_t list_start = 0; size_t list_start = 0;
size_t list_start_counted = 0;
size_t text_start = 0; size_t text_start = 0;
bool differ = false; bool differ = false;
for (; list_start < state.list.size() && text_start < text.size();) { for (; list_start < state.list.size() && text_start < text.size();) {
@ -201,6 +207,7 @@ struct TextDocument {
list_start++; list_start++;
text_start++; text_start++;
list_start_counted++;
} }
// doc and text dont differ // doc and text dont differ
@ -214,7 +221,10 @@ struct TextDocument {
// +1 so i can have unsigned // +1 so i can have unsigned
size_t list_end = state.list.size(); size_t list_end = state.list.size();
size_t text_end = text.size(); size_t text_end = text.size();
for (; list_end > 0 && text_end > 0 && list_end >= list_start && text_end >= text_start;) { //for (; list_end > 0 && text_end > 0 && list_end >= list_start && text_end >= text_start;) {
//while (list_end >= list_start && text_end >= text_start) {
size_t list_end_counted = 0;
while (list_start_counted - list_end_counted > state.doc_size && text_end >= text_start) {
// jump over tombstones // jump over tombstones
if (!state.list[list_end-1].value.has_value()) { if (!state.list[list_end-1].value.has_value()) {
list_end--; list_end--;
@ -227,6 +237,7 @@ struct TextDocument {
list_end--; list_end--;
text_end--; text_end--;
list_end_counted++;
} }
//std::cout << "list_end: " << list_end << " text_end: " << text_end << "\n"; //std::cout << "list_end: " << list_end << " text_end: " << text_end << "\n";
@ -237,7 +248,7 @@ struct TextDocument {
if (list_start <= list_end && list_start < state.list.size()) { if (list_start <= list_end && list_start < state.list.size()) {
ops = delRange( ops = delRange(
state.list[list_start].id, state.list[list_start].id,
list_end < state.list.size() ? std::make_optional(state.list[list_end].id) : std::nullopt (list_start == list_end ? list_end+1 : list_end) < state.list.size() ? std::make_optional(state.list[list_end].id) : std::nullopt
); );
//std::cout << "deleted: " << ops.size() << "\n"; //std::cout << "deleted: " << ops.size() << "\n";
} }

View File

@ -5,6 +5,7 @@
#include <random> #include <random>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <variant>
// single letter agent, for testing only // single letter agent, for testing only
using Agent = char; using Agent = char;
@ -411,6 +412,91 @@ void testBugSame(void) {
assert(doc.getText() == new_text2); assert(doc.getText() == new_text2);
} }
void testBugDoubleDel(void) {
Doc doc;
doc.local_agent = 'A';
{
std::string_view new_text{"a"};
doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{""};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
assert(ops.size() == 1);
assert(std::holds_alternative<ListType::OpDel>(ops.front()));
assert(std::get<ListType::OpDel>(ops.front()).id.seq == 0);
}
{
std::string_view new_text{""};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
assert(ops.size() == 0);
}
}
void testBugSameDel(void) {
Doc doc;
doc.local_agent = 'A';
{
std::string_view new_text{"a"};
doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{"aa"};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{"a"};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
}
}
void testBugSameDel2(void) {
Doc doc;
doc.local_agent = 'A';
{
std::string_view new_text{"a"};
doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{"aa"};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{"aaa"};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{"aa"};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
}
{
std::string_view new_text{"a"};
const auto ops = doc.merge(new_text);
assert(doc.getText() == new_text);
}
}
int main(void) { int main(void) {
const size_t loops = 1'000; const size_t loops = 1'000;
{ {
@ -469,10 +555,31 @@ int main(void) {
std::cout << std::string(40, '=') << "\n"; std::cout << std::string(40, '=') << "\n";
{ {
std::cout << "testBugNLNL:\n"; std::cout << "testBugSame:\n";
testBugSame(); testBugSame();
} }
std::cout << std::string(40, '=') << "\n";
{
std::cout << "testBugDoubleDel:\n";
testBugDoubleDel();
}
std::cout << std::string(40, '=') << "\n";
{
std::cout << "testBugSameDel:\n";
testBugSameDel();
}
std::cout << std::string(40, '=') << "\n";
{
std::cout << "testBugSameDel2:\n";
testBugSameDel2();
}
return 0; return 0;
} }

View File

@ -210,8 +210,8 @@ int main(void) {
doc.local_agent = remote_address.port; // tmp: use local port as id doc.local_agent = remote_address.port; // tmp: use local port as id
while (true) { while (true) {
// 10MiB // 100MiB
auto buffer = std::make_unique<std::array<uint8_t, 1024*1024*10>>(); auto buffer = std::make_unique<std::array<uint8_t, 1024*1024*100>>();
int64_t bytes_received {0}; int64_t bytes_received {0};
bytes_received = zed_net_tcp_socket_receive(&remote_socket, buffer->data(), buffer->size()); bytes_received = zed_net_tcp_socket_receive(&remote_socket, buffer->data(), buffer->size());