forked from organicmaps/organicmaps
[omim] Removed raw pointers in favour of shared_ptr in trie.
This commit is contained in:
parent
edfbda47a7
commit
764a72f50b
9 changed files with 68 additions and 70 deletions
|
@ -107,16 +107,15 @@ void ReadAllValues(trie::SuccinctTrieIterator<MemReader, SimpleValueReader> & ro
|
|||
values.push_back(root.GetValue(i));
|
||||
}
|
||||
|
||||
void CollectInSubtree(
|
||||
unique_ptr<trie::SuccinctTrieIterator<MemReader, SimpleValueReader>> const & root,
|
||||
vector<uint8_t> & collectedValues)
|
||||
void CollectInSubtree(trie::SuccinctTrieIterator<MemReader, SimpleValueReader> & root,
|
||||
vector<uint8_t> & collectedValues)
|
||||
{
|
||||
ReadAllValues(*root.get(), collectedValues);
|
||||
ReadAllValues(root, collectedValues);
|
||||
|
||||
if (auto l = root->GoToEdge(0))
|
||||
CollectInSubtree(l, collectedValues);
|
||||
if (auto r = root->GoToEdge(1))
|
||||
CollectInSubtree(r, collectedValues);
|
||||
if (auto l = root.GoToEdge(0))
|
||||
CollectInSubtree(*l, collectedValues);
|
||||
if (auto r = root.GoToEdge(1))
|
||||
CollectInSubtree(*r, collectedValues);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -188,9 +187,10 @@ UNIT_TEST(SuccinctTrie_Iterator)
|
|||
using TEmptyValue = trie::EmptyValueReader::ValueType;
|
||||
|
||||
auto trieRoot = trie::ReadSuccinctTrie(memReader, SimpleValueReader());
|
||||
TEST(trieRoot, ());
|
||||
|
||||
vector<uint8_t> collectedValues;
|
||||
CollectInSubtree(trieRoot, collectedValues);
|
||||
CollectInSubtree(*trieRoot, collectedValues);
|
||||
sort(collectedValues.begin(), collectedValues.end());
|
||||
TEST_EQUAL(collectedValues.size(), 5, ());
|
||||
for (size_t i = 0; i < collectedValues.size(); ++i)
|
||||
|
|
|
@ -238,7 +238,7 @@ UNIT_TEST(TrieBuilder_Build)
|
|||
|
||||
MemReader memReader = MemReader(&serial[0], serial.size());
|
||||
using IteratorType = trie::Iterator<trie::FixedSizeValueReader<4>::ValueType>;
|
||||
unique_ptr<IteratorType> const root(trie::ReadTrie(memReader, trie::FixedSizeValueReader<4>()));
|
||||
auto const root = trie::ReadTrie(memReader, trie::FixedSizeValueReader<4>());
|
||||
vector<KeyValuePair> res;
|
||||
KeyValuePairBackInserter f;
|
||||
trie::ForEachRef(*root, f, vector<trie::TrieChar>());
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "base/macros.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
#include "std/unique_ptr.hpp"
|
||||
#include "std/utility.hpp"
|
||||
#include "std/vector.hpp"
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include "base/base.hpp"
|
||||
#include "base/buffer_vector.hpp"
|
||||
|
||||
#include "std/unique_ptr.hpp"
|
||||
|
||||
#include "std/shared_ptr.hpp"
|
||||
|
||||
namespace trie
|
||||
{
|
||||
|
@ -34,8 +33,8 @@ public:
|
|||
|
||||
virtual ~Iterator() {}
|
||||
|
||||
virtual Iterator<TValue> * Clone() const = 0;
|
||||
virtual Iterator<TValue> * GoToEdge(size_t i) const = 0;
|
||||
virtual shared_ptr<Iterator<TValue>> Clone() const = 0;
|
||||
virtual shared_ptr<Iterator<TValue>> GoToEdge(size_t i) const = 0;
|
||||
};
|
||||
|
||||
struct EmptyValueReader
|
||||
|
@ -75,8 +74,8 @@ void ForEachRef(Iterator<TValue> const & iter, F & f, TString const & s)
|
|||
{
|
||||
TString s1(s);
|
||||
s1.insert(s1.end(), iter.m_edge[i].m_str.begin(), iter.m_edge[i].m_str.end());
|
||||
unique_ptr<Iterator<TValue>> const pIter1(iter.GoToEdge(i));
|
||||
ForEachRef(*pIter1, f, s1);
|
||||
auto it = iter.GoToEdge(i);
|
||||
ForEachRef(*it, f, s1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ template <class TValueReader>
|
|||
class LeafIterator0 : public Iterator<typename TValueReader::ValueType>
|
||||
{
|
||||
public:
|
||||
typedef typename TValueReader::ValueType ValueType;
|
||||
using ValueType = typename TValueReader::ValueType;
|
||||
|
||||
template <class TReader>
|
||||
LeafIterator0(TReader const & reader, TValueReader const & valueReader)
|
||||
|
@ -33,9 +33,12 @@ public:
|
|||
}
|
||||
|
||||
// trie::Iterator overrides:
|
||||
Iterator<ValueType> * Clone() const override { return new LeafIterator0<TValueReader>(*this); }
|
||||
shared_ptr<Iterator<ValueType>> Clone() const override
|
||||
{
|
||||
return make_shared<LeafIterator0<TValueReader>>(*this);
|
||||
}
|
||||
|
||||
Iterator<ValueType> * GoToEdge(size_t i) const override
|
||||
shared_ptr<Iterator<ValueType>> GoToEdge(size_t i) const override
|
||||
{
|
||||
ASSERT(false, (i));
|
||||
UNUSED_VALUE(i);
|
||||
|
@ -71,9 +74,12 @@ public:
|
|||
}
|
||||
|
||||
// trie::Iterator overrides:
|
||||
Iterator<ValueType> * Clone() const override { return new Iterator0<TReader, TValueReader>(*this); }
|
||||
shared_ptr<Iterator<ValueType>> Clone() const override
|
||||
{
|
||||
return make_shared<Iterator0<TReader, TValueReader>>(*this);
|
||||
}
|
||||
|
||||
Iterator<ValueType> * GoToEdge(size_t i) const override
|
||||
shared_ptr<Iterator<ValueType>> GoToEdge(size_t i) const override
|
||||
{
|
||||
ASSERT_LESS(i, this->m_edge.size(), ());
|
||||
uint32_t const offset = m_edgeInfo[i].m_offset;
|
||||
|
@ -87,10 +93,10 @@ public:
|
|||
SharedMemReader memReader(size);
|
||||
m_reader.Read(offset, memReader.Data(), size);
|
||||
if (m_edgeInfo[i].m_isLeaf)
|
||||
return new LeafIterator0<SharedMemReader, TValueReader>(
|
||||
return make_shared<LeafIterator0<SharedMemReader, TValueReader>>(
|
||||
memReader, m_valueReader);
|
||||
else
|
||||
return new Iterator0<SharedMemReader, TValueReader>(
|
||||
return make_shared<Iterator0<SharedMemReader, TValueReader>>(
|
||||
memReader, m_valueReader,
|
||||
this->m_edge[i].m_str.back());
|
||||
}
|
||||
|
@ -98,10 +104,11 @@ public:
|
|||
*/
|
||||
{
|
||||
if (m_edgeInfo[i].m_isLeaf)
|
||||
return new LeafIterator0<TValueReader>(m_reader.SubReader(offset, size), m_valueReader);
|
||||
return make_shared<LeafIterator0<TValueReader>>(m_reader.SubReader(offset, size),
|
||||
m_valueReader);
|
||||
else
|
||||
return new Iterator0<TReader, TValueReader>(m_reader.SubReader(offset, size), m_valueReader,
|
||||
this->m_edge[i].m_str.back());
|
||||
return make_shared<Iterator0<TReader, TValueReader>>(
|
||||
m_reader.SubReader(offset, size), m_valueReader, this->m_edge[i].m_str.back());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,10 +190,10 @@ private:
|
|||
|
||||
// Returns iterator to the root of the trie.
|
||||
template <class TReader, class TValueReader>
|
||||
Iterator<typename TValueReader::ValueType> * ReadTrie(TReader const & reader,
|
||||
TValueReader valueReader = TValueReader())
|
||||
shared_ptr<Iterator<typename TValueReader::ValueType>> ReadTrie(
|
||||
TReader const & reader, TValueReader valueReader = TValueReader())
|
||||
{
|
||||
return new Iterator0<TReader, TValueReader>(reader, valueReader, DEFAULT_CHAR);
|
||||
return make_shared<Iterator0<TReader, TValueReader>>(reader, valueReader, DEFAULT_CHAR);
|
||||
}
|
||||
|
||||
} // namespace trie
|
||||
|
|
|
@ -200,8 +200,8 @@ namespace feature
|
|||
feature::DataHeader header(container);
|
||||
serial::CodingParams cp(trie::GetCodingParams(header.GetDefCodingParams()));
|
||||
|
||||
unique_ptr<trie::DefaultIterator> const pTrieRoot(
|
||||
trie::ReadTrie(container.GetReader(SEARCH_INDEX_FILE_TAG), trie::ValueReader(cp)));
|
||||
auto const pTrieRoot =
|
||||
trie::ReadTrie(container.GetReader(SEARCH_INDEX_FILE_TAG), trie::ValueReader(cp));
|
||||
|
||||
SearchTokensCollector f;
|
||||
trie::ForEachRef(*pTrieRoot, f, strings::UniString());
|
||||
|
|
|
@ -30,15 +30,14 @@ size_t CalcEqualLength(TSrcIter b, TSrcIter e, TCompIter bC, TCompIter eC)
|
|||
return count;
|
||||
}
|
||||
|
||||
inline trie::DefaultIterator * MoveTrieIteratorToString(trie::DefaultIterator const & trieRoot,
|
||||
strings::UniString const & queryS,
|
||||
size_t & symbolsMatched,
|
||||
bool & bFullEdgeMatched)
|
||||
inline shared_ptr<trie::DefaultIterator> MoveTrieIteratorToString(
|
||||
trie::DefaultIterator const & trieRoot, strings::UniString const & queryS,
|
||||
size_t & symbolsMatched, bool & bFullEdgeMatched)
|
||||
{
|
||||
symbolsMatched = 0;
|
||||
bFullEdgeMatched = false;
|
||||
|
||||
unique_ptr<trie::DefaultIterator> pIter(trieRoot.Clone());
|
||||
auto it = trieRoot.Clone();
|
||||
|
||||
size_t const szQuery = queryS.size();
|
||||
|
||||
|
@ -46,22 +45,19 @@ inline trie::DefaultIterator * MoveTrieIteratorToString(trie::DefaultIterator co
|
|||
{
|
||||
bool bMatched = false;
|
||||
|
||||
ASSERT_LESS(pIter->m_edge.size(), std::numeric_limits<uint32_t>::max(), ());
|
||||
uint32_t const edgeCount = static_cast<uint32_t>(pIter->m_edge.size());
|
||||
ASSERT_LESS(it->m_edge.size(), std::numeric_limits<uint32_t>::max(), ());
|
||||
uint32_t const edgeCount = static_cast<uint32_t>(it->m_edge.size());
|
||||
|
||||
for (uint32_t i = 0; i < edgeCount; ++i)
|
||||
{
|
||||
size_t const szEdge = pIter->m_edge[i].m_str.size();
|
||||
size_t const szEdge = it->m_edge[i].m_str.size();
|
||||
|
||||
size_t const count = CalcEqualLength(
|
||||
pIter->m_edge[i].m_str.begin(),
|
||||
pIter->m_edge[i].m_str.end(),
|
||||
queryS.begin() + symbolsMatched,
|
||||
queryS.end());
|
||||
size_t const count = CalcEqualLength(it->m_edge[i].m_str.begin(), it->m_edge[i].m_str.end(),
|
||||
queryS.begin() + symbolsMatched, queryS.end());
|
||||
|
||||
if ((count > 0) && (count == szEdge || szQuery == count + symbolsMatched))
|
||||
{
|
||||
pIter.reset(pIter->GoToEdge(i));
|
||||
it = it->GoToEdge(i);
|
||||
|
||||
bFullEdgeMatched = (count == szEdge);
|
||||
symbolsMatched += count;
|
||||
|
@ -73,7 +69,7 @@ inline trie::DefaultIterator * MoveTrieIteratorToString(trie::DefaultIterator co
|
|||
if (!bMatched)
|
||||
return NULL;
|
||||
}
|
||||
return pIter->Clone();
|
||||
return it->Clone();
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -104,10 +100,9 @@ void FullMatchInTrie(trie::DefaultIterator const & trieRoot, strings::UniChar co
|
|||
|
||||
size_t symbolsMatched = 0;
|
||||
bool bFullEdgeMatched;
|
||||
unique_ptr<trie::DefaultIterator> const pIter(
|
||||
MoveTrieIteratorToString(trieRoot, s, symbolsMatched, bFullEdgeMatched));
|
||||
auto const it = MoveTrieIteratorToString(trieRoot, s, symbolsMatched, bFullEdgeMatched);
|
||||
|
||||
if (!pIter || (!s.empty() && !bFullEdgeMatched) || symbolsMatched != s.size())
|
||||
if (!it || (!s.empty() && !bFullEdgeMatched) || symbolsMatched != s.size())
|
||||
return;
|
||||
|
||||
#if defined(OMIM_OS_IPHONE) && !defined(__clang__)
|
||||
|
@ -117,8 +112,8 @@ void FullMatchInTrie(trie::DefaultIterator const & trieRoot, strings::UniChar co
|
|||
#endif
|
||||
|
||||
ASSERT_EQUAL ( symbolsMatched, s.size(), () );
|
||||
for (size_t i = 0; i < pIter->m_value.size(); ++i)
|
||||
f(pIter->m_value[i]);
|
||||
for (size_t i = 0; i < it->m_value.size(); ++i)
|
||||
f(it->m_value[i]);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
|
@ -128,38 +123,34 @@ void PrefixMatchInTrie(trie::DefaultIterator const & trieRoot, strings::UniChar
|
|||
if (!CheckMatchString(rootPrefix, rootPrefixSize, s))
|
||||
return;
|
||||
|
||||
using TQueue = vector<trie::DefaultIterator *>;
|
||||
using TQueue = vector<shared_ptr<trie::DefaultIterator>>;
|
||||
TQueue trieQueue;
|
||||
{
|
||||
size_t symbolsMatched = 0;
|
||||
bool bFullEdgeMatched;
|
||||
trie::DefaultIterator * pRootIter =
|
||||
MoveTrieIteratorToString(trieRoot, s, symbolsMatched, bFullEdgeMatched);
|
||||
auto const it = MoveTrieIteratorToString(trieRoot, s, symbolsMatched, bFullEdgeMatched);
|
||||
|
||||
UNUSED_VALUE(symbolsMatched);
|
||||
UNUSED_VALUE(bFullEdgeMatched);
|
||||
|
||||
if (!pRootIter)
|
||||
if (!it)
|
||||
return;
|
||||
|
||||
trieQueue.push_back(pRootIter);
|
||||
trieQueue.push_back(it);
|
||||
}
|
||||
|
||||
// 'f' can throw an exception. So be prepared to delete unprocessed elements.
|
||||
MY_SCOPE_GUARD(doDelete, GetRangeDeletor(trieQueue, DeleteFunctor()));
|
||||
|
||||
while (!trieQueue.empty())
|
||||
{
|
||||
// Next 2 lines don't throw any exceptions while moving
|
||||
// ownership from container to smart pointer.
|
||||
unique_ptr<trie::DefaultIterator> const pIter(trieQueue.back());
|
||||
auto const it = trieQueue.back();
|
||||
trieQueue.pop_back();
|
||||
|
||||
for (size_t i = 0; i < pIter->m_value.size(); ++i)
|
||||
f(pIter->m_value[i]);
|
||||
for (size_t i = 0; i < it->m_value.size(); ++i)
|
||||
f(it->m_value[i]);
|
||||
|
||||
for (size_t i = 0; i < pIter->m_edge.size(); ++i)
|
||||
trieQueue.push_back(pIter->GoToEdge(i));
|
||||
for (size_t i = 0; i < it->m_edge.size(); ++i)
|
||||
trieQueue.push_back(it->GoToEdge(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,7 +341,7 @@ bool MatchCategoriesInTrie(SearchQueryParams const & params, trie::DefaultIterat
|
|||
ASSERT_GREATER_OR_EQUAL(edge.size(), 1, ());
|
||||
if (edge[0] == search::kCategoriesLang)
|
||||
{
|
||||
unique_ptr<trie::DefaultIterator> const catRoot(trieRoot.GoToEdge(langIx));
|
||||
auto const catRoot = trieRoot.GoToEdge(langIx);
|
||||
MatchTokensInTrie(params.m_tokens, TrieRootPrefix(*catRoot, edge), holder);
|
||||
|
||||
// Last token's prefix is used as a complete token here, to
|
||||
|
@ -380,7 +371,7 @@ void ForEachLangPrefix(SearchQueryParams const & params, trie::DefaultIterator c
|
|||
int8_t const lang = static_cast<int8_t>(edge[0]);
|
||||
if (edge[0] < search::kCategoriesLang && params.IsLangExist(lang))
|
||||
{
|
||||
unique_ptr<trie::DefaultIterator> const langRoot(trieRoot.GoToEdge(langIx));
|
||||
auto const langRoot = trieRoot.GoToEdge(langIx);
|
||||
TrieRootPrefix langPrefix(*langRoot, edge);
|
||||
toDo(langPrefix, lang);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ void RetrieveAddressFeatures(MwmSet::MwmHandle const & handle, SearchQueryParams
|
|||
ASSERT(value, ());
|
||||
serial::CodingParams codingParams(trie::GetCodingParams(value->GetHeader().GetDefCodingParams()));
|
||||
ModelReaderPtr searchReader = value->m_cont.GetReader(SEARCH_INDEX_FILE_TAG);
|
||||
unique_ptr<trie::DefaultIterator> const trieRoot(trie::ReadTrie(
|
||||
SubReaderWrapper<Reader>(searchReader.GetPtr()), trie::ValueReader(codingParams)));
|
||||
auto const trieRoot = trie::ReadTrie(SubReaderWrapper<Reader>(searchReader.GetPtr()),
|
||||
trie::ValueReader(codingParams));
|
||||
|
||||
MatchFeaturesInTrie(params, *trieRoot, EmptyFilter(), forward<ToDo>(toDo));
|
||||
}
|
||||
|
|
|
@ -1565,8 +1565,8 @@ void Query::SearchLocality(MwmValue const * pMwm, Locality & res1, Region & res2
|
|||
|
||||
ModelReaderPtr searchReader = pMwm->m_cont.GetReader(SEARCH_INDEX_FILE_TAG);
|
||||
|
||||
unique_ptr<trie::DefaultIterator> const trieRoot(
|
||||
trie::ReadTrie(SubReaderWrapper<Reader>(searchReader.GetPtr()), trie::ValueReader(cp)));
|
||||
auto const trieRoot =
|
||||
trie::ReadTrie(SubReaderWrapper<Reader>(searchReader.GetPtr()), trie::ValueReader(cp));
|
||||
|
||||
ForEachLangPrefix(params, *trieRoot, [&](TrieRootPrefix & langRoot, int8_t lang)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue