diff --git a/indexer/index.hpp b/indexer/index.hpp index 7ae0af75a2..c8cd4a1ead 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -257,9 +257,7 @@ template class UniqueOffsetAdapter : public BaseT { public: // Defines base Query type. - // If someone in BaseT want's to do that, use the following line and pass query in ForEachXXX(). - // class Query : public typename BaseT::Query - class Query + class Query : public BaseT::Query { // TODO: Remember max offsets.size() and initialize offsets with it? unordered_set m_Offsets; @@ -277,7 +275,7 @@ public: Query & query) const { UniqueOffsetFunctorAdapter uniqueOffsetFunctorAdapter(query.m_Offsets, f); - BaseT::ForEachInIntervalAndScale(uniqueOffsetFunctorAdapter, beg, end, scale); + BaseT::ForEachInIntervalAndScale(uniqueOffsetFunctorAdapter, beg, end, scale, query); } private: diff --git a/indexer/interval_index.hpp b/indexer/interval_index.hpp index a319d1175a..6153e5207c 100644 --- a/indexer/interval_index.hpp +++ b/indexer/interval_index.hpp @@ -40,6 +40,14 @@ template class IntervalIndex : public IntervalIndexBase { public: + + class Query + { + private: + friend class IntervalIndex; + vector m_IntervalIndexCache; + }; + IntervalIndex(ReaderT const & reader, int cellIdBytes = 5) : m_Reader(reader), m_CellIdBytes(cellIdBytes) { @@ -48,18 +56,26 @@ public: } template - void ForEach(F const & f, uint64_t beg, uint64_t end) const + void ForEach(F const & f, uint64_t beg, uint64_t end, Query & query) const { ASSERT_LESS(beg, 1ULL << 8 * m_CellIdBytes, (beg, end)); ASSERT_LESS_OR_EQUAL(end, 1ULL << 8 * m_CellIdBytes, (beg, end)); // end is inclusive in ForEachImpl(). --end; - ForEachImpl(f, beg, end, m_Level0Index, m_CellIdBytes - 1); + ForEachImpl(f, beg, end, m_Level0Index, m_CellIdBytes - 1, query); + } + + template + void ForEach(F const & f, uint64_t beg, uint64_t end) const + { + Query query; + ForEach(f, beg, end, query); } private: template - void ForEachImpl(F const & f, uint64_t beg, uint64_t end, Index const & index, int level) const + void ForEachImpl(F const & f, uint64_t beg, uint64_t end, Index const & index, int level, + Query & query) const { uint32_t const beg0 = static_cast(beg >> (8 * level)); uint32_t const end0 = static_cast(end >> (8 * level)); @@ -78,7 +94,7 @@ private: { Index index1; ReadIndex(index.GetBaseOffset() + (cumCount * sizeof(Index)), index1); - ForEachImpl(f, b1, e1, index1, level - 1); + ForEachImpl(f, b1, e1, index1, level - 1, query); } else { @@ -86,9 +102,10 @@ private: uint32_t const step = sizeof(ValueT) + m_Header.m_CellIdLeafBytes; uint32_t const count = index.m_Count[i]; uint32_t pos = index.GetBaseOffset() + (cumCount * step); - vector data(step * count); - char const * pData = &data[0]; - m_Reader.Read(pos, &data[0], data.size()); + size_t const readSize = step * count; + query.m_IntervalIndexCache.assign(readSize, 0); + char * pData = &query.m_IntervalIndexCache[0]; + m_Reader.Read(pos, pData, readSize); for (uint32_t j = 0; j < count; ++j, pData += step) // for (uint32_t j = 0; j < count; ++j, pos += step) { diff --git a/indexer/scale_index.hpp b/indexer/scale_index.hpp index 7042f6cea8..f1be3abdb3 100644 --- a/indexer/scale_index.hpp +++ b/indexer/scale_index.hpp @@ -55,6 +55,8 @@ class ScaleIndex : public ScaleIndexBase { public: typedef ReaderT ReaderType; + typedef IntervalIndex IntervalIndexType; + typedef typename IntervalIndexType::Query Query; ScaleIndex() {} explicit ScaleIndex(ReaderT const & reader) { Attach(reader); } @@ -70,15 +72,15 @@ public: } template - void ForEachInIntervalAndScale(F const & f, uint64_t beg, uint64_t end, uint32_t scale) const + void ForEachInIntervalAndScale(F const & f, uint64_t beg, uint64_t end, uint32_t scale, + Query & query) const { int scaleBucket = BucketByScale(scale); ASSERT_LESS(scaleBucket, static_cast(m_IndexForScale.size()), ()); for (int i = 0; i <= scaleBucket; ++i) - m_IndexForScale[i].ForEach(f, beg, end); + m_IndexForScale[i].ForEach(f, beg, end, query); } private: - typedef IntervalIndex IntervalIndexType; vector m_IndexForScale; };