Add magic/version to "cacheFormat": "msgpack"

This commit is contained in:
Fangrui Song 2018-01-27 19:21:35 -08:00
parent 41eb1c863c
commit aeb63ce3ad
3 changed files with 30 additions and 7 deletions

View File

@ -565,7 +565,9 @@ void OnIndexReference_Function(IndexFile* db,
} // namespace
// static
int IndexFile::kCurrentVersion = 10;
const int IndexFile::kCurrentVersion = 10;
const uint64_t IndexFile::kMessagePackMagic = 0x6371657279;
const int IndexFile::kMessagePackVersion = 0;
IndexFile::IndexFile(const std::string& path,
const optional<std::string>& contents)

View File

@ -479,7 +479,13 @@ MAKE_REFLECT_TYPE_PROXY(LanguageId, std::underlying_type<LanguageId>::type);
struct IndexFile {
IdCache id_cache;
static int kCurrentVersion;
static const int kCurrentVersion;
static const uint64_t kMessagePackMagic;
// MessagePack cache files have its own version number.
// JSON has good forward compatibility because field addition/deletion do not
// harm but currently no efforts have been made to make old MessagePack cache
// files accepted by newer cquery.
static const int kMessagePackVersion;
int version = 0;
std::string path;

View File

@ -271,6 +271,10 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
msgpack::sbuffer buf;
msgpack::packer<msgpack::sbuffer> pk(&buf);
MessagePackWriter msgpack_writer(&pk);
uint64_t magic = IndexFile::kMessagePackMagic;
int version = IndexFile::kMessagePackVersion;
Reflect(msgpack_writer, magic);
Reflect(msgpack_writer, version);
Reflect(msgpack_writer, file);
return std::string(buf.data(), buf.size());
}
@ -305,7 +309,7 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
try {
Reflect(json_reader, *file);
} catch (std::invalid_argument& e) {
LOG_S(ERROR) << "'" << path << "': failed to deserialize "
LOG_S(INFO) << "'" << path << "': failed to deserialize "
<< json_reader.GetPath() << "."
<< e.what();
return nullptr;
@ -317,18 +321,29 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
if (serialized.empty())
return nullptr;
try {
uint64_t magic;
int version;
if (serialized.size() < 8)
throw std::invalid_argument("Invalid");
msgpack::unpacker upk;
upk.reserve_buffer(serialized.size());
memcpy(upk.buffer(), serialized.data(), serialized.size());
upk.buffer_consumed(serialized.size());
file = MakeUnique<IndexFile>(path, nullopt);
MessagePackReader reader(&upk);
Reflect(reader, *file);
if (file->version != expected_version)
Reflect(reader, magic);
if (magic != IndexFile::kMessagePackMagic)
throw std::invalid_argument("Invalid magic");
Reflect(reader, version);
if (version != IndexFile::kMessagePackVersion) {
LOG_S(INFO) << "'" << path << "': skip old msgpack version "
<< IndexFile::kMessagePackVersion;
return nullptr;
}
Reflect(reader, *file);
} catch (std::invalid_argument& e) {
LOG_S(ERROR) << "'" << path << "': failed to deserialize msgpack "
<< e.what();
LOG_S(INFO) << "Failed to deserialize msgpack '" << path
<< "': " << e.what();
return nullptr;
}
break;