mirror of
https://github.com/logos-messaging/negentropy.git
synced 2026-01-07 16:33:07 +00:00
get rid of IdListResponse to simplify protocol
This commit is contained in:
parent
a1b6eed1a4
commit
fd33c9a8b2
@ -136,7 +136,7 @@ struct Negentropy {
|
|||||||
|
|
||||||
while (query.size()) {
|
while (query.size()) {
|
||||||
auto currBound = decodeBound(query, lastTimestampIn);
|
auto currBound = decodeBound(query, lastTimestampIn);
|
||||||
auto mode = decodeVarInt(query); // 0 = Skip, 1 = Fingerprint, 2 = IdList, 3 = IdListResponse
|
auto mode = decodeVarInt(query); // 0 = Skip, 1 = Fingerprint, 2 = IdList
|
||||||
|
|
||||||
auto lower = prevIndex;
|
auto lower = prevIndex;
|
||||||
auto upper = std::upper_bound(prevIndex, items.end(), currBound);
|
auto upper = std::upper_bound(prevIndex, items.end(), currBound);
|
||||||
@ -166,16 +166,12 @@ struct Negentropy {
|
|||||||
theirElems.emplace(e, TheirElem{i, false});
|
theirElems.emplace(e, TheirElem{i, false});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> responseHaveIds;
|
|
||||||
std::vector<uint64_t> responseNeedIndices;
|
|
||||||
|
|
||||||
for (auto it = lower; it < upper; ++it) {
|
for (auto it = lower; it < upper; ++it) {
|
||||||
auto e = theirElems.find(std::string(it->getId()));
|
auto e = theirElems.find(std::string(it->getId()));
|
||||||
|
|
||||||
if (e == theirElems.end()) {
|
if (e == theirElems.end()) {
|
||||||
// ID exists on our side, but not their side
|
// ID exists on our side, but not their side
|
||||||
if (isInitiator) haveIds.emplace_back(it->getId());
|
if (isInitiator) haveIds.emplace_back(it->getId());
|
||||||
else responseHaveIds.emplace_back(it->getId());
|
|
||||||
} else {
|
} else {
|
||||||
// ID exists on both sides
|
// ID exists on both sides
|
||||||
e->second.onBothSides = true;
|
e->second.onBothSides = true;
|
||||||
@ -186,36 +182,23 @@ struct Negentropy {
|
|||||||
if (!v.onBothSides) {
|
if (!v.onBothSides) {
|
||||||
// ID exists on their side, but not our side
|
// ID exists on their side, but not our side
|
||||||
if (isInitiator) needIds.emplace_back(k);
|
if (isInitiator) needIds.emplace_back(k);
|
||||||
else responseNeedIndices.emplace_back(v.offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isInitiator) {
|
if (!isInitiator) {
|
||||||
std::string payload = encodeVarInt(3); // mode = IdListResponse
|
std::vector<std::string> responseHaveIds;
|
||||||
|
|
||||||
|
for (auto it = lower; it < upper; ++it) {
|
||||||
|
responseHaveIds.emplace_back(it->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string payload = encodeVarInt(2); // mode = IdList
|
||||||
|
|
||||||
payload += encodeVarInt(responseHaveIds.size());
|
payload += encodeVarInt(responseHaveIds.size());
|
||||||
for (const auto &id : responseHaveIds) payload += id;
|
for (const auto &id : responseHaveIds) payload += id;
|
||||||
|
|
||||||
auto bitField = encodeBitField(responseNeedIndices);
|
|
||||||
payload += encodeVarInt(bitField.size());
|
|
||||||
payload += bitField;
|
|
||||||
|
|
||||||
outputs.emplace_back(BoundOutput({ prevBound, currBound, std::move(payload) }));
|
outputs.emplace_back(BoundOutput({ prevBound, currBound, std::move(payload) }));
|
||||||
}
|
}
|
||||||
} else if (mode == 3) { // IdListResponse
|
|
||||||
if (!isInitiator) throw negentropy::err("unexpected IdListResponse");
|
|
||||||
|
|
||||||
auto numIds = decodeVarInt(query);
|
|
||||||
for (uint64_t i = 0; i < numIds; i++) {
|
|
||||||
needIds.emplace_back(getBytes(query, idSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto bitFieldSize = decodeVarInt(query);
|
|
||||||
auto bitField = getBytes(query, bitFieldSize);
|
|
||||||
|
|
||||||
for (auto it = lower; it < upper; ++it) {
|
|
||||||
if (bitFieldLookup(bitField, it - lower)) haveIds.emplace_back(it->getId());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw negentropy::err("unexpected mode");
|
throw negentropy::err("unexpected mode");
|
||||||
}
|
}
|
||||||
@ -298,6 +281,7 @@ struct Negentropy {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Decoding
|
// Decoding
|
||||||
|
|
||||||
std::string getBytes(std::string_view &encoded, size_t n) {
|
std::string getBytes(std::string_view &encoded, size_t n) {
|
||||||
@ -396,21 +380,6 @@ struct Negentropy {
|
|||||||
return XorElem(curr.timestamp, currKey.substr(0, sharedPrefixBytes + 1));
|
return XorElem(curr.timestamp, currKey.substr(0, sharedPrefixBytes + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encodeBitField(const std::vector<uint64_t> inds) {
|
|
||||||
if (inds.size() == 0) return "";
|
|
||||||
uint64_t max = *std::max_element(inds.begin(), inds.end());
|
|
||||||
|
|
||||||
std::string bitField = std::string((max + 8) / 8, '\0');
|
|
||||||
for (auto ind : inds) bitField[ind / 8] |= 1 << ind % 8;
|
|
||||||
|
|
||||||
return bitField;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bitFieldLookup(const std::string &bitField, uint64_t ind) {
|
|
||||||
if ((ind + 8) / 8 > bitField.size()) return false;
|
|
||||||
return !!(bitField[ind / 8] & 1 << (ind % 8));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user