[omim] Removed raw pointers in favour of shared_ptr in trie.

This commit is contained in:
Maxim Pimenov 2015-09-25 22:03:42 +03:00 committed by Sergey Yershov
parent edfbda47a7
commit 764a72f50b
9 changed files with 68 additions and 70 deletions

View file

@ -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)

View file

@ -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>());

View file

@ -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"

View file

@ -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);
}
}

View file

@ -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

View file

@ -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());

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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)
{