forked from organicmaps/organicmaps
trie::builder::Build(), not finished.
This commit is contained in:
parent
ebf4eb294c
commit
77e91a25e3
2 changed files with 75 additions and 24 deletions
|
@ -9,14 +9,6 @@
|
|||
namespace
|
||||
{
|
||||
|
||||
struct ValueWriter
|
||||
{
|
||||
template <typename SinkT, typename ValueT> void Write(SinkT & sink, ValueT x)
|
||||
{
|
||||
WriteToSink(sink, x);
|
||||
}
|
||||
};
|
||||
|
||||
struct ChildNodeInfo
|
||||
{
|
||||
bool m_isLeaf;
|
||||
|
@ -35,7 +27,6 @@ UNIT_TEST(TrieBuilder_WriteNode_Smoke)
|
|||
{
|
||||
vector<uint8_t> serial;
|
||||
PushBackByteSink<vector<uint8_t> > sink(serial);
|
||||
string const values = "123";
|
||||
ChildNodeInfo children[] =
|
||||
{
|
||||
{true, 1, "1A"},
|
||||
|
@ -43,7 +34,7 @@ UNIT_TEST(TrieBuilder_WriteNode_Smoke)
|
|||
{false, 3, "zz"},
|
||||
{true, 4, "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"}
|
||||
};
|
||||
trie::builder::WriteNode(sink, ValueWriter(), 0, values.begin(), values.end(),
|
||||
trie::builder::WriteNode(sink, 0, 3, "123", 3,
|
||||
&children[0], &children[0] + ARRAY_SIZE(children));
|
||||
unsigned char const expected [] =
|
||||
{
|
||||
|
|
|
@ -8,19 +8,17 @@ namespace trie
|
|||
namespace builder
|
||||
{
|
||||
|
||||
template <typename SinkT, typename ValueWriter, typename ValueIterT>
|
||||
void WriteLeaf(SinkT & sink, ValueWriter valueWriter, ValueIterT begValue, ValueIterT endValue)
|
||||
template <typename SinkT, typename ChildIterT>
|
||||
void WriteNode(SinkT & sink, strings::UniChar baseChar,
|
||||
uint32_t const valueCount, void const * valuesData, uint32_t const valuesSize,
|
||||
ChildIterT const begChild, ChildIterT const endChild)
|
||||
{
|
||||
for (ValueIterT it = begValue; it != endValue; ++it)
|
||||
valueWriter.Write(sink, *it);
|
||||
}
|
||||
|
||||
template <typename SinkT, typename ValueWriter, typename ValueIterT, typename ChildIterT>
|
||||
void WriteNode(SinkT & sink, ValueWriter valueWriter, strings::UniChar baseChar,
|
||||
ValueIterT begValue, ValueIterT endValue,
|
||||
ChildIterT begChild, ChildIterT endChild)
|
||||
{
|
||||
uint32_t const valueCount = endValue - begValue;
|
||||
if (begChild == endChild)
|
||||
{
|
||||
// Leaf node.
|
||||
sink.Write(valuesData, valuesSize);
|
||||
return;
|
||||
}
|
||||
uint32_t const childCount = endChild - begChild;
|
||||
uint8_t const header = static_cast<uint32_t>((min(valueCount, 3U) << 6) + min(childCount, 63U));
|
||||
sink.Write(&header, 1);
|
||||
|
@ -28,8 +26,7 @@ void WriteNode(SinkT & sink, ValueWriter valueWriter, strings::UniChar baseChar,
|
|||
WriteVarUint(sink, valueCount);
|
||||
if (childCount >= 63)
|
||||
WriteVarUint(sink, childCount);
|
||||
for (ValueIterT it = begValue; it != endValue; ++it)
|
||||
valueWriter.Write(sink, *it);
|
||||
sink.Write(valuesData, valuesSize);
|
||||
for (ChildIterT it = begChild; it != endChild; ++it)
|
||||
{
|
||||
WriteVarUint(sink, it->Size());
|
||||
|
@ -66,6 +63,69 @@ void WriteNode(SinkT & sink, ValueWriter valueWriter, strings::UniChar baseChar,
|
|||
}
|
||||
}
|
||||
|
||||
struct ChildInfo
|
||||
{
|
||||
bool m_isLeaf;
|
||||
uint32_t m_size;
|
||||
char const * m_edge;
|
||||
uint32_t Size() const { return m_size; }
|
||||
bool IsLeaf() const { return m_isLeaf; }
|
||||
strings::UniString GetEdge() const { return strings::MakeUniString(m_edge); }
|
||||
};
|
||||
|
||||
struct NodeInfo
|
||||
{
|
||||
NodeInfo(uint64_t pos, strings::UniChar uniChar) : m_begPos(pos), m_char(uniChar) {}
|
||||
uint64_t m_begPos;
|
||||
strings::UniChar m_char;
|
||||
buffer_vector<ChildInfo, 4> m_children;
|
||||
buffer_vector<uint8_t, 32> m_values;
|
||||
};
|
||||
|
||||
void PopNodes(vector<builder::NodeInfo> & nodes, int nodesToPop)
|
||||
{
|
||||
if (nodesToPop == 0)
|
||||
return;
|
||||
ASSERT_GREATER_OR_EQUAL(nodes.size(), nodesToPop, ());
|
||||
strings::UniString reverseEdge;
|
||||
while (nodesToPop > 0)
|
||||
{
|
||||
reverseEdge.push_back(nodes.back().m_char);reverseEdge.push_back(nodes.back().m_char);
|
||||
if (nodes.back().m_values.empty() && nodes.back().m_children.size() <= 1)
|
||||
{
|
||||
ASSERT_EQUAL(nodes.back().m_children.size(), 1, ());
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace builder
|
||||
|
||||
/*
|
||||
template <typename SinkT, typename IterT>
|
||||
void Build(SinkT & sink, IterT const beg, IterT const end)
|
||||
{
|
||||
vector<builder::NodeInfo> nodes;
|
||||
strings::UniString prevKey;
|
||||
for (IterT it = beg; it != end; ++it)
|
||||
{
|
||||
strings::UniString const key = it->Key();
|
||||
CHECK(!key.empty(), ());
|
||||
CHECK_LESS_OR_EQUAL(prevKey, key, ());
|
||||
int nCommon = 0;
|
||||
while (nCommon < min(key.size(),prevKey.size()) && prevKey[nCommon] == key[nCommon])
|
||||
++nCommon;
|
||||
builder::PopNodes(nodes, nodes.size() - nCommon);
|
||||
uint64_t const pos = sink.Pos();
|
||||
for (int i = nCommon; i < key.size(); ++i)
|
||||
nodes.push_back(NodeInfo(pos, key[i]));
|
||||
uint8_t const * pValue = static_cast<uint8_t const *>(it->ValueData());
|
||||
nodes.back().m_values.insert(nodes.back().m_values.end(), pValue, pValue + it->ValueSize());
|
||||
prevKey.swap(key);
|
||||
}
|
||||
builder::PopNodes(nodes.size());
|
||||
}
|
||||
*/
|
||||
|
||||
} // namespace trie
|
||||
|
|
Loading…
Add table
Reference in a new issue