diff options
author | Yuri Gorshenin <y@maps.me> | 2015-09-07 16:08:07 +0300 |
---|---|---|
committer | Sergey Yershov <yershov@corp.mail.ru> | 2016-03-23 16:02:13 +0300 |
commit | 070a14d8accf1f23330ee743b3bf10593ff42563 (patch) | |
tree | 7b2046d9319d73f1ef6a9b54826cc67dfcc68cd6 /indexer/rank_table.cpp | |
parent | 5e5befb58ef0b2a424cffdfd102d7d6aa7ffce82 (diff) |
Review fixes.
Diffstat (limited to 'indexer/rank_table.cpp')
-rw-r--r-- | indexer/rank_table.cpp | 134 |
1 files changed, 78 insertions, 56 deletions
diff --git a/indexer/rank_table.cpp b/indexer/rank_table.cpp index b7a500b19e..34484f7e84 100644 --- a/indexer/rank_table.cpp +++ b/indexer/rank_table.cpp @@ -3,7 +3,6 @@ #include "indexer/data_header.hpp" #include "indexer/feature_algo.hpp" #include "indexer/feature_utils.hpp" -#include "indexer/features_offsets_table.hpp" #include "indexer/features_vector.hpp" #include "indexer/types_skipper.hpp" @@ -11,6 +10,8 @@ #include "coding/endianness.hpp" #include "coding/file_container.hpp" +#include "coding/file_writer.hpp" +#include "coding/reader.hpp" #include "coding/simple_dense_coding.hpp" #include "coding/succinct_mapper.hpp" #include "coding/writer.hpp" @@ -25,19 +26,31 @@ namespace search { +namespace +{ uint64_t const kVersionOffset = 0; uint64_t const kFlagsOffset = 1; uint64_t const kHeaderSize = 8; -namespace +enum class CheckResult { -// Returns true when flags claim that the serialized data has the same -// endianness as a host. -bool SameEndianness(uint8_t flags) + CorruptedHeader, + EndiannessMismatch, + EndiannessMatch +}; + +template <typename TReader> +CheckResult CheckEndianness(TReader && reader) { + if (reader.Size() < kHeaderSize) + return CheckResult::CorruptedHeader; + uint8_t flags; + reader.Read(kFlagsOffset, &flags, sizeof(flags)); bool const isHostBigEndian = IsBigEndian(); bool const isDataBigEndian = flags & 1; - return isHostBigEndian == isDataBigEndian; + if (isHostBigEndian != isDataBigEndian) + return CheckResult::EndiannessMismatch; + return CheckResult::EndiannessMatch; } class MemoryRegion @@ -101,17 +114,19 @@ unique_ptr<MappedMemoryRegion> GetMemoryRegionForTag(FilesMappingContainer & mco return make_unique<MappedMemoryRegion>(move(handle)); } -class RankTableV1 : public RankTable +// RankTable version 1, uses simple dense coding to store and access +// array of ranks. +class RankTableV0 : public RankTable { public: - RankTableV1() = default; + RankTableV0() = default; - RankTableV1(vector<uint8_t> const & ranks) : m_coding(ranks) {} + RankTableV0(vector<uint8_t> const & ranks) : m_coding(ranks) {} // RankTable overrides: uint8_t Get(uint64_t i) const override { return m_coding.Get(i); } uint64_t Size() const override { return m_coding.Size(); } - RankTable::Version GetVersion() const override { return V1; } + RankTable::Version GetVersion() const override { return V0; } void Serialize(Writer & writer) override { static uint64_t const padding = 0; @@ -124,36 +139,46 @@ public: Freeze(m_coding, writer, "SimpleDenseCoding"); } - // Loads rank table v1 from a raw memory region. - static unique_ptr<RankTableV1> Load(unique_ptr<MappedMemoryRegion> && region) + // Loads RankTableV0 from a raw memory region. + static unique_ptr<RankTableV0> Load(unique_ptr<MappedMemoryRegion> && region) { - if (!region.get() || region->Size() < kHeaderSize) - return unique_ptr<RankTableV1>(); + if (!region.get()) + return unique_ptr<RankTableV0>(); - uint8_t const flags = region->ImmutableData()[kFlagsOffset]; - if (!SameEndianness(flags)) - return unique_ptr<RankTableV1>(); + auto const result = CheckEndianness(MemReader(region->ImmutableData(), region->Size())); + if (result != CheckResult::EndiannessMatch) + return unique_ptr<RankTableV0>(); - unique_ptr<RankTableV1> table(new RankTableV1()); + unique_ptr<RankTableV0> table(new RankTableV0()); coding::Map(table->m_coding, region->ImmutableData() + kHeaderSize, "SimpleDenseCoding"); table->m_region = move(region); return table; } - // Loads rank table v1 from a raw memory region. Modifies region in + // Loads RankTableV0 from a raw memory region. Modifies region in // the case of endianness mismatch. - static unique_ptr<RankTableV1> Load(unique_ptr<CopiedMemoryRegion> && region) + static unique_ptr<RankTableV0> Load(unique_ptr<CopiedMemoryRegion> && region) { - if (!region.get() || region->Size() < kHeaderSize) - return unique_ptr<RankTableV1>(); - - unique_ptr<RankTableV1> table(new RankTableV1()); - uint8_t const flags = region->ImmutableData()[kFlagsOffset]; - if (SameEndianness(flags)) - coding::Map(table->m_coding, region->ImmutableData() + kHeaderSize, "SimpleDenseCoding"); - else - coding::ReverseMap(table->m_coding, region->MutableData() + kHeaderSize, "SimpleDenseCoding"); - table->m_region = move(region); + if (!region.get()) + return unique_ptr<RankTableV0>(); + + unique_ptr<RankTableV0> table; + switch (CheckEndianness(MemReader(region->ImmutableData(), region->Size()))) + { + case CheckResult::CorruptedHeader: + break; + case CheckResult::EndiannessMismatch: + table.reset(new RankTableV0()); + coding::ReverseMap(table->m_coding, region->MutableData() + kHeaderSize, + "SimpleDenseCoding"); + table->m_region = move(region); + break; + case CheckResult::EndiannessMatch: + table.reset(new RankTableV0()); + coding::Map(table->m_coding, region->ImmutableData() + kHeaderSize, "SimpleDenseCoding"); + table->m_region = move(region); + break; + } return table; } @@ -181,11 +206,11 @@ void SerializeRankTable(RankTable & table, FilesContainerW & wcont) // Deserializes rank table from a rank section. Returns null when it's // not possible to load a rank table (no rank section, corrupted -// header, endianness mismatch for a mapped mwm).. +// header, endianness mismatch for a mapped mwm). template <typename TRegion> unique_ptr<RankTable> LoadRankTable(unique_ptr<TRegion> && region) { - if (!region || !region->ImmutableData() || region->Size() < 8) + if (!region || !region->ImmutableData() || region->Size() < kHeaderSize) { LOG(LERROR, ("Invalid RankTable format.")); return unique_ptr<RankTable>(); @@ -195,8 +220,8 @@ unique_ptr<RankTable> LoadRankTable(unique_ptr<TRegion> && region) static_cast<RankTable::Version>(region->ImmutableData()[kVersionOffset]); switch (version) { - case RankTable::V1: - return RankTableV1::Load(move(region)); + case RankTable::V0: + return RankTableV0::Load(move(region)); } return unique_ptr<RankTable>(); } @@ -216,8 +241,6 @@ uint8_t CalcSearchRank(FeatureType const & ft) } } // namespace -RankTable::~RankTable() {} - // static unique_ptr<RankTable> RankTable::Load(FilesContainerR & rcont) { @@ -234,10 +257,7 @@ unique_ptr<RankTable> RankTable::Load(FilesMappingContainer & mcont) void RankTableBuilder::CalcSearchRanks(FilesContainerR & rcont, vector<uint8_t> & ranks) { feature::DataHeader header(rcont); - unique_ptr<feature::FeaturesOffsetsTable> offsetsTable = - feature::FeaturesOffsetsTable::CreateIfNotExistsAndLoad(rcont); - ASSERT(offsetsTable.get(), ()); - FeaturesVector featuresVector(rcont, header, offsetsTable.get()); + FeaturesVector featuresVector(rcont, header, nullptr /* features offsets table */); featuresVector.ForEach([&ranks](FeatureType const & ft, uint32_t /* index */) { @@ -255,23 +275,25 @@ void RankTableBuilder::Create(platform::LocalCountryFile const & localFile) FilesContainerR rcont(mapPath); if (rcont.IsExist(RANKS_FILE_TAG)) { - auto reader = rcont.GetReader(RANKS_FILE_TAG); - if (reader.Size() >= kHeaderSize) + switch (CheckEndianness(rcont.GetReader(RANKS_FILE_TAG))) { - uint8_t flags; - reader.Read(kFlagsOffset, &flags, sizeof(flags)); - - if (SameEndianness(flags)) + case CheckResult::CorruptedHeader: + { + // Worst case - we need to create rank table from scratch. + break; + } + case CheckResult::EndiannessMismatch: + { + // Try to copy whole serialized data and instantiate table via reverse mapping. + auto region = GetMemoryRegionForTag(rcont, RANKS_FILE_TAG); + table = LoadRankTable(move(region)); + break; + } + case CheckResult::EndiannessMatch: { - // Feature rank table already exists and has correct - // endianess. Nothing to do here. + // Table exists and has proper format. Nothing to do here. return; } - - // Copy whole serialized table and try to deserialize it via - // reverse mapping. - auto region = GetMemoryRegionForTag(rcont, RANKS_FILE_TAG); - table = LoadRankTable(move(region)); } } @@ -281,19 +303,19 @@ void RankTableBuilder::Create(platform::LocalCountryFile const & localFile) { vector<uint8_t> ranks; CalcSearchRanks(rcont, ranks); - table = make_unique<RankTableV1>(ranks); + table = make_unique<RankTableV0>(ranks); } } ASSERT(table.get(), ()); - FilesContainerW wcont(mapPath); + FilesContainerW wcont(mapPath, FileWriter::OP_WRITE_EXISTING); SerializeRankTable(*table, wcont); } // static void RankTableBuilder::Create(vector<uint8_t> const & ranks, FilesContainerW & wcont) { - RankTableV1 table(ranks); + RankTableV0 table(ranks); SerializeRankTable(table, wcont); } } // namespace search |