in glean/rts/ownership/setu32.cpp [310:384]
void SetU32::appendMerge(SetU32::Block left, SetU32::Block right) {
struct Local {
static void mergeSparse(
SetU32& set,
uint32_t id,
std::vector<uint8_t>::const_iterator ls,
uint8_t ln,
std::vector<uint8_t>::const_iterator rs,
uint8_t rn) {
uint8_t n = 0;
while (ln != 0 && rn != 0 && fitsSparse(n,1)) {
const auto l = *ls;
const auto r = *rs;
set.sparse.push_back(l <= r ? l : r);
++n;
if (l <= r) {
++ls;
--ln;
}
if (r <= l) {
++rs;
--rn;
}
}
if (fitsSparse(n, ln+rn)) {
set.hdrs.push_back(Hdr::sparse(id, n+ln+rn));
set.sparse.insert(set.sparse.end(), ls, ls+ln);
set.sparse.insert(set.sparse.end(), rs, rs+rn);
} else {
const auto dense = Bits256(&*(set.sparse.end()-n),n).with(&*ls,ln).with(&*rs,rn);
set.hdrs.push_back(Hdr::dense(id));
set.dense.push_back(dense);
set.sparse.resize(set.sparse.size()-n);
}
}
};
switch(left.hdr.type()) {
case SetU32::Hdr::Sparse:
switch(right.hdr.type()) {
case SetU32::Hdr::Sparse:
Local::mergeSparse(*this, left.hdr.id(), left.sparse, left.hdr.sparseLen(), right.sparse, right.hdr.sparseLen());
break;
case SetU32::Hdr::Dense:
append(left.hdr.id(), right.dense->with(&*left.sparse, left.hdr.sparseLen()));
break;
case SetU32::Hdr::Full:
hdrs.push_back(right.hdr);
break;
}
break;
case SetU32::Hdr::Dense:
switch (right.hdr.type()) {
case SetU32::Hdr::Sparse:
append(left.hdr.id(), left.dense->with(&*right.sparse, right.hdr.sparseLen()));
break;
case SetU32::Hdr::Dense:
append(left.hdr.id(), *left.dense | *right.dense);
break;
case SetU32::Hdr::Full:
hdrs.push_back(right.hdr);
break;
}
break;
case SetU32::Hdr::Full:
hdrs.push_back(left.hdr);
break;
}
}