refactor(util/object_serializer): add methods write_core and read_core that allows to pack information in the byte used to indicate whether an object is already in the cache or not

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-12-29 19:59:53 -08:00
parent dbd122301a
commit de77851a00
5 changed files with 59 additions and 38 deletions

Binary file not shown.

Binary file not shown.

View file

@ -357,17 +357,21 @@ public:
}
void write(expr const & a) {
super::write(a, [&]() {
auto k = a.kind();
char kc;
if (k == expr_kind::App && num_args(a) < g_small_app_num_args) {
kc = static_cast<char>(g_first_app_size_kind + num_args(a));
} else {
kc = static_cast<char>(k);
}
super::write_core(a, kc, [&]() {
serializer & s = get_owner();
auto k = a.kind();
if (k == expr_kind::App && num_args(a) < g_small_app_num_args) {
if (kc >= static_cast<char>(g_first_app_size_kind)) {
// compressed application
s << static_cast<char>(g_first_app_size_kind + num_args(a));
for (unsigned i = 0; i < num_args(a); i++)
write(arg(a, i));
return;
}
s << static_cast<char>(k);
switch (k) {
case expr_kind::Var: s << var_idx(a); break;
case expr_kind::Constant: s << const_name(a); write(const_type(a)); break;
@ -401,9 +405,8 @@ public:
}
expr read() {
return super::read([&]() {
return super::read_core([&](char c) {
deserializer & d = get_owner();
char c = d.read_char();
if (c >= g_first_app_size_kind) {
// compressed application
unsigned num = c - g_first_app_size_kind;

View file

@ -357,25 +357,29 @@ name operator+(name const & n1, name const & n2) {
}
}
enum name_ll_kind { LL_ANON = 0, LL_STRING = 1, LL_INT = 2, LL_STRING_PREFIX = 3, LL_INT_PREFIX = 4 };
name_ll_kind ll_kind(name const & n) {
if (n.is_anonymous())
return LL_ANON;
if (n.is_atomic())
return n.is_string() ? LL_STRING : LL_INT;
else
return n.is_string() ? LL_STRING_PREFIX : LL_INT_PREFIX;
}
class name_serializer : public object_serializer<name, name::ptr_hash, name::ptr_eq> {
typedef object_serializer<name, name::ptr_hash, name::ptr_eq> super;
public:
void write(name const & n) {
super::write(n, [&]() {
name_ll_kind k = ll_kind(n);
super::write_core(n, k, [&]() {
serializer & s = get_owner();
s.write_char(static_cast<char>(n.kind()));
if (n.is_anonymous())
return;
if (n.is_atomic()) {
s.write_bool(false);
} else {
s.write_bool(true);
write(n.get_prefix());
}
if (n.is_string()) {
s.write_string(n.get_string());
} else {
s.write_unsigned(n.get_numeral());
switch (k) {
case LL_ANON: break;
case LL_STRING: s.write_string(n.get_string()); break;
case LL_INT: s.write_unsigned(n.get_numeral()); break;
case LL_STRING_PREFIX: write(n.get_prefix()); s.write_string(n.get_string()); break;
case LL_INT_PREFIX: write(n.get_prefix()); s.write_unsigned(n.get_numeral()); break;
}
});
}
@ -385,20 +389,22 @@ class name_deserializer : public object_deserializer<name> {
typedef object_deserializer<name> super;
public:
name read() {
return super::read([&]() {
return super::read_core([&](char c) {
deserializer & d = get_owner();
auto k = static_cast<name_kind>(d.read_char());
if (k == name_kind::ANONYMOUS)
return name();
name prefix;
if (d.read_bool())
prefix = read();
if (k == name_kind::STRING) {
name_ll_kind k = static_cast<name_ll_kind>(c);
switch (k) {
case LL_ANON: return name();
case LL_STRING: return name(d.read_string().c_str());
case LL_INT: return name(name(), d.read_unsigned());
case LL_STRING_PREFIX: {
name prefix = read();
return name(prefix, d.read_string().c_str());
} else {
lean_assert(k == name_kind::NUMERAL);
return name(prefix, d.read_unsigned());
}
case LL_INT_PREFIX: {
name prefix = read();
return name(prefix, d.read_unsigned());
}}
lean_unreachable(); // LCOV_EXCL_LINE
});
}
};

View file

@ -22,19 +22,25 @@ class object_serializer : public serializer::extension {
std::unordered_map<T, unsigned, HashFn, EqFn> m_table;
public:
object_serializer(HashFn const & h = HashFn(), EqFn const & e = EqFn()):m_table(LEAN_OBJECT_SERIALIZER_BUCKET_SIZE, h, e) {}
template<typename F>
void write(T const & v, F && f) {
void write_core(T const & v, char k, F && f) {
auto it = m_table.find(v);
serializer & s = get_owner();
if (it == m_table.end()) {
s.write_bool(true);
s.write_char(k + 1);
f();
m_table.insert(std::make_pair(v, m_table.size()));
} else {
s.write_bool(false);
s.write_char(0);
s.write_unsigned(it->second);
}
}
template<typename F>
void write(T const & v, F && f) {
write_core(v, 0, f);
}
};
/**
@ -45,10 +51,11 @@ class object_deserializer : public deserializer::extension {
std::vector<T> m_table;
public:
template<typename F>
T read(F && f) {
T read_core(F && f) {
deserializer & d = get_owner();
if (d.read_bool()) {
T r = f();
char c = d.read_char();
if (c > 0) {
T r = f(c-1);
m_table.push_back(r);
return r;
} else {
@ -57,5 +64,10 @@ public:
return m_table[i];
}
}
template<typename F>
T read(F && f) {
return read_core([&](char ) { return f(); });
}
};
}