Mailinglist Archive: zypp-devel (227 mails)
| < Previous | Next > |
Re: [zypp-devel] implementing PoolQuery iterator using sat-solver's Dataiterator
- From: Josef Reidinger <jreidinger@xxxxxxx>
- Date: Thu, 03 Apr 2008 13:49:54 +0200
- Message-id: <47F4C462.5010906@xxxxxxx>
Jan Kupec wrote:
I think that have query tight linked to result of some repo search is not good idea, because it prevent some optimalization (like now if someone want query on name and kind f.e. thunar and patch - you must search thrue all repository with this, but you can use name index on pool and have it significantly fast).
So I think better is use own storage for results (so you shade how you implement query search) and iterate over it.
Little performance note - if you add flag dirty which is set to true everytime you change query settings and recreate result only if is set, then you can save some searching (for example if someone want two time iterate over same results).
if I understand it, own storage can help with this problem.
If used dirty flag, iterator is invalidate only when you change query settings.
If you don't want invalidate iterator you must have some iterator with reference counting pointer to old storage and always create dynamically new.
--
To unsubscribe, e-mail: zypp-devel+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: zypp-devel+help@xxxxxxxxxxxx
I have the following experimental PoolQuery::ResultIterator
extern "C"
{
#include "satsolver/repo.h";
}
class PoolQuery
{
public:
typedef ::_Dataiterator RepoDataIterator;
class ResultIterator : public boost::iterator_adaptor<
ResultIterator // Derived
, RepoDataIterator * // Base
, const sat::Solvable // Value
, boost::forward_traversal_tag // CategoryOrTraversal
, const sat::Solvable & // Reference
>
I think that have query tight linked to result of some repo search is not good idea, because it prevent some optimalization (like now if someone want query on name and kind f.e. thunar and patch - you must search thrue all repository with this, but you can use name index on pool and have it significantly fast).
So I think better is use own storage for results (so you shade how you implement query search) and iterate over it.
{
public:
ResultIterator()
: ResultIterator::iterator_adaptor_(0)
{ _rdit = 0; base_reference() = 0; }
ResultIterator(RepoDataIterator * rdit)
: ResultIterator::iterator_adaptor_(0)
{ _rdit = rdit; base_reference() = rdit; }
private:
friend class boost::iterator_core_access;
sat::Solvable dereference() const
{
return _rdit ? sat::Solvable(_rdit->solvid) :
sat::Solvable::noSolvable;
}
void increment()
{
if (::dataiterator_step(_rdit))
else
{
base_reference() = 0;
}
}
template <class OtherDerived, class OtherIterator, class V, class
C, class R, class D>
bool equal( const boost::iterator_adaptor<OtherDerived,
OtherIterator, V, C, R, D> & rhs ) const;
{
if (!rhs.base() && !base())
return true;
if (!rhs.base() || !base())
return false;
// quite useless since base() == rhs.base() always except for
// end()
if (rhs.base()->solvid == base()->solvid)
return true;
return false;
}
private:
RepoDataIterator * _rdit;
};
// PoolQuery methods&members go here....
}
I use (maybe wrongly) the RepoDataIterator * as the base.
RepoDataIterator is being created in PoolQuery::Impl, the begin() and
end() methods look like this:
PoolQuery::ResultIterator PoolQuery::Impl::begin()
{
sat::Pool pool(sat::Pool::instance());
sat::Pool::RepositoryIterator itr = pool.reposBegin();
::dataiterator_init(&_rdit, itr->get(), 0 /*p*/, 0/*keyname*/, 0
/*matchstring*/, _flags);
INT << "next: " << ::dataiterator_step(&_rdit) << endl;
return PoolQuery::ResultIterator(&_rdit);
}
Little performance note - if you add flag dirty which is set to true everytime you change query settings and recreate result only if is set, then you can save some searching (for example if someone want two time iterate over same results).
PoolQuery::ResultIterator PoolQuery::Impl::end()
{
return PoolQuery::ResultIterator(0);
}
This has (at least :O) two drawbacks:
1) RepoDataIterator * is the same in all instances except for those
created with PoolQuery::end()
if I understand it, own storage can help with this problem.
2) PoolQuery::begin() always resets the dataiterator state for all
existing instances
If used dirty flag, iterator is invalidate only when you change query settings.
If you don't want invalidate iterator you must have some iterator with reference counting pointer to old storage and always create dynamically new.
This is probably a really bad evil. Can somebody (ma? :O) give me a
pointer how to do it better? I would very much love to discover the
world by myself, but the time is unfortunately running out :O(
Please ignore the fact that this does not iterate across repositories
for now; and that it iterates through solvable attributes, not just the
solvables.
cheers,
jano
--
To unsubscribe, e-mail: zypp-devel+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: zypp-devel+help@xxxxxxxxxxxx
| < Previous | Next > |