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-02 15:44:15 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:02:12 +0300
commitb4bd3a3e802fc25665b7cbcb2a2af2d45b79913c (patch)
tree97de276e0c92ae9a36984dfcf747a0e36457ca10 /coding/simple_dense_coding.cpp
parent122fdfda89f513028bf5636b3c6812dbc530aced (diff)
Review fixes.
Diffstat (limited to 'coding/simple_dense_coding.cpp')
-rw-r--r--coding/simple_dense_coding.cpp84
1 files changed, 43 insertions, 41 deletions
diff --git a/coding/simple_dense_coding.cpp b/coding/simple_dense_coding.cpp
index f2e4acfb95..03d88f1b8a 100644
--- a/coding/simple_dense_coding.cpp
+++ b/coding/simple_dense_coding.cpp
@@ -9,6 +9,8 @@ namespace coding
{
namespace
{
+size_t const kAlphabetSize = static_cast<size_t>(numeric_limits<uint8_t>::max()) + 1;
+
struct Code
{
Code() : m_code(0), m_length(0) {}
@@ -17,42 +19,44 @@ struct Code
uint8_t m_length;
};
-size_t const kAlphabetSize = static_cast<size_t>(numeric_limits<uint8_t>::max()) + 1;
-Code g_codeTable[kAlphabetSize];
-bool g_codeTableInitialized = false;
-
-// Returns pointer to an initialized code table. If necessary,
-// initializes it. In the latter case, code table is filled with
-// following code words: 0, 1, 00, 01, 10, 11, 000, 001, ...
-Code const * GetCodeTable()
+// Initializes code table for simple dense coding with following code
+// words: 0, 1, 00, 01, 10, 11, 000, 001, ...
+struct CodeTable
{
- if (g_codeTableInitialized)
- return g_codeTable;
-
- unsigned length = 1;
- size_t rank = 0;
- while (rank < kAlphabetSize)
+public:
+ CodeTable()
{
- // Number of codes with the same bit length.
- size_t const numCodes = static_cast<size_t>(1) << length;
-
- size_t base = rank;
- while (rank - base < numCodes && rank < kAlphabetSize)
+ size_t rank = 0;
+ uint8_t length = 1;
+ while (rank < kAlphabetSize)
{
- g_codeTable[rank].m_code = rank - base;
- g_codeTable[rank].m_length = length;
- ++rank;
+ // Number of codes with the same bit length.
+ size_t const numCodes = static_cast<size_t>(1) << length;
+
+ uint8_t code = 0;
+ for (; code < numCodes && rank + code < kAlphabetSize; ++code)
+ {
+ size_t const pos = rank + code;
+ m_table[pos].m_code = code;
+ m_table[pos].m_length = length;
+ }
+
+ rank += code;
+ length += 1;
}
+ }
- ++length;
+ inline Code const & GetCode(uint8_t rank) const
+ {
+ return m_table[rank];
}
- g_codeTableInitialized = true;
- return g_codeTable;
-}
+private:
+ Code m_table[kAlphabetSize];
+};
-// Computes frequences for data symbols.
-void GetFrequences(vector<uint8_t> const & data, uint64_t frequency[])
+// Calculates frequences for data symbols.
+void CalcFrequences(vector<uint8_t> const & data, uint64_t frequency[])
{
memset(frequency, 0, sizeof(*frequency) * kAlphabetSize);
for (uint8_t symbol : data)
@@ -62,8 +66,11 @@ void GetFrequences(vector<uint8_t> const & data, uint64_t frequency[])
SimpleDenseCoding::SimpleDenseCoding(vector<uint8_t> const & data)
{
+ // This static initialization isn't thread safe prior to C++11.
+ static CodeTable codeTable;
+
uint64_t frequency[kAlphabetSize]; // Maps symbols to frequences.
- GetFrequences(data, frequency);
+ CalcFrequences(data, frequency);
uint8_t symbols[kAlphabetSize]; // Maps ranks to symbols.
uint8_t rank[kAlphabetSize]; // Maps symbols to ranks.
@@ -77,27 +84,22 @@ SimpleDenseCoding::SimpleDenseCoding(vector<uint8_t> const & data)
for (size_t r = 0; r < kAlphabetSize; ++r)
rank[symbols[r]] = r;
- Code const * codeTable = GetCodeTable();
- ASSERT(codeTable, ());
-
uint64_t bitLength = 0;
for (size_t symbol = 0; symbol < kAlphabetSize; ++symbol)
- bitLength += static_cast<uint64_t>(frequency[symbol]) * codeTable[rank[symbol]].m_length;
+ bitLength += frequency[symbol] * codeTable.GetCode(rank[symbol]).m_length;
succinct::bit_vector_builder bitsBuilder;
bitsBuilder.reserve(bitLength);
vector<bool> indexBuilder(bitLength);
size_t pos = 0;
+ for (uint8_t symbol : data)
{
- for (uint8_t symbol : data)
- {
- Code const & code = codeTable[rank[symbol]];
- ASSERT_LESS(pos, bitLength, ());
- indexBuilder[pos] = 1;
+ Code const & code = codeTable.GetCode(rank[symbol]);
+ ASSERT_LESS(pos, bitLength, ());
+ indexBuilder[pos] = 1;
- bitsBuilder.append_bits(code.m_code, code.m_length);
- pos += code.m_length;
- }
+ bitsBuilder.append_bits(code.m_code, code.m_length);
+ pos += code.m_length;
}
ASSERT_EQUAL(pos, bitLength, ());