Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Gorshenin <y@maps.me>2015-09-07 16:08:07 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:02:13 +0300
commit070a14d8accf1f23330ee743b3bf10593ff42563 (patch)
tree7b2046d9319d73f1ef6a9b54826cc67dfcc68cd6 /indexer/rank_table.cpp
parent5e5befb58ef0b2a424cffdfd102d7d6aa7ffce82 (diff)
Review fixes.
Diffstat (limited to 'indexer/rank_table.cpp')
-rw-r--r--indexer/rank_table.cpp134
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