summaryrefslogtreecommitdiff
path: root/libopie2/opiepim
authoreilers <eilers>2004-08-29 12:50:18 (UTC)
committer eilers <eilers>2004-08-29 12:50:18 (UTC)
commit679d9fef2673eea18fe5d9c85df2b10b09a8a250 (patch) (side-by-side diff)
tree8b3d6dbef45568be6f5daac31094d6e599fdefdf /libopie2/opiepim
parent45327ef3c0f093fc227682f79158632afc09e6d1 (diff)
downloadopie-679d9fef2673eea18fe5d9c85df2b10b09a8a250.zip
opie-679d9fef2673eea18fe5d9c85df2b10b09a8a250.tar.gz
opie-679d9fef2673eea18fe5d9c85df2b10b09a8a250.tar.bz2
Added lookahead caching for addressbook (SQL-only) for speed improvement.
Diffstat (limited to 'libopie2/opiepim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp154
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_sql.h5
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h28
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h40
-rw-r--r--libopie2/opiepim/core/opimtemplatebase.h16
5 files changed, 196 insertions, 47 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
index dda23cc..abfd944 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp
@@ -301,26 +301,27 @@ namespace {
}
QString FindQuery::query()const{
-// if ( m_uids.count() == 0 )
- return single();
+ if ( m_uids.count() == 0 )
+ return single();
+ else
+ return multi();
}
- /*
- else
- return multi();
- }
- QString FindQuery::multi()const {
- QString qu = "select uid, type, value from addressbook where";
- for (uint i = 0; i < m_uids.count(); i++ ) {
- qu += " UID = " + QString::number( m_uids[i] ) + " OR";
- }
- qu.remove( qu.length()-2, 2 ); // Hmmmm..
- return qu;
+
+ QString FindQuery::multi()const {
+ QString qu = "select * from addressbook where";
+ for (uint i = 0; i < m_uids.count(); i++ ) {
+ qu += " uid = " + QString::number( m_uids[i] ) + " OR";
+ }
+ qu.remove( qu.length()-2, 2 ); // Hmmmm..
+
+ odebug << "find query: " << qu << "" << oendl;
+ return qu;
}
- */
- QString FindQuery::single()const{
- QString qu = "select *";
- qu += " from addressbook where uid = " + QString::number(m_uid);
- // owarn << "find query: " << qu << "" << oendl;
- return qu;
+ QString FindQuery::single()const{
+ QString qu = "select *";
+ qu += " from addressbook where uid = " + QString::number(m_uid);
+
+ // owarn << "find query: " << qu << "" << oendl;
+ return qu;
}
@@ -474,5 +475,5 @@ bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact )
OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
{
- odebug << "OPimContactAccessBackend_SQL::find()" << oendl;
+ odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl;
QTime t;
t.start();
@@ -485,4 +486,45 @@ OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const
}
+OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const
+{
+ odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl;
+ odebug << "searching for " << uid << "" << oendl;
+
+ QTime t;
+ t.start();
+
+ uint numReadAhead = readAhead();
+ QArray<int> searchList( numReadAhead );
+
+ uint size =0;
+
+ // Build an array with all elements which should be requested and cached
+ // We will just request "numReadAhead" elements, starting from "current" position in
+ // the list of many uids !
+ switch( direction ) {
+ /* forward */
+ case Frontend::Forward:
+ for ( uint i = current; i < queryUids.count() && size < numReadAhead; i++ ) {
+ searchList[size] = queryUids[i];
+ size++;
+ }
+ break;
+ /* reverse */
+ case Frontend::Reverse:
+ for ( uint i = current; i != 0 && size < numReadAhead; i-- ) {
+ searchList[size] = queryUids[i];
+ size++;
+ }
+ break;
+ }
+
+ //Shrink to real size..
+ searchList.resize( size );
+
+ OPimContact retContact( requestContactsAndCache( uid, searchList ) );
+
+ odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl;
+ return retContact;
+}
@@ -769,6 +811,4 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co
t.start();
- QMap<int, QString> nonCustomMap;
-
int t2needed = 0;
int t3needed = 0;
@@ -781,6 +821,65 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co
OSQLResultItem resItem = res_noncustom.first();
+ QMap<int, QString> nonCustomMap;
QTime t3;
t3.start();
+ nonCustomMap = fillNonCustomMap( resItem );
+ t3needed = t3.elapsed();
+
+
+ // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
+ odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
+ << " ms, mapping: " << t3needed << " ms" << oendl;
+
+ return nonCustomMap;
+}
+
+/* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */
+OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const
+{
+ // We want to get all contacts with one query.
+ // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h).
+ // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned
+ // by using the cache..
+ QArray<int> cachelist = uidlist;
+
+ odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl;
+
+ QTime t;
+ t.start();
+
+ int t2needed = 0;
+ int t3needed = 0;
+ QTime t2;
+ t2.start();
+ FindQuery query( cachelist );
+ OSQLResult res_noncustom = m_driver->query( &query );
+ t2needed = t2.elapsed();
+
+ QMap<int, QString> nonCustomMap;
+ QTime t3;
+ t3.start();
+ OSQLResultItem resItem = res_noncustom.first();
+ do {
+ OPimContact contact( fillNonCustomMap( resItem ) );
+ contact.setExtraMap( requestCustom( contact.uid() ) );
+ odebug << "Caching uid: " << contact.uid() << oendl;
+ cache( contact );
+ resItem = res_noncustom.next();
+ } while ( ! res_noncustom.atEnd() ); //atEnd() is true if we are past(!) the list !!
+ t3needed = t3.elapsed();
+
+
+ // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
+ odebug << "RequestContactsAndCache needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
+ << " ms, mapping: " << t3needed << " ms" << oendl;
+
+ return cacheFind( uid );
+}
+
+QMap<int, QString> OPimContactAccessBackend_SQL::fillNonCustomMap( const OSQLResultItem& resultItem ) const
+{
+ QMap<int, QString> nonCustomMap;
+
// Now loop through all columns
QStringList fieldList = OPimContactFields::untrfields( false );
@@ -791,5 +890,5 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co
int id = translate[*it];
- QString value = resItem.data( (*it) );
+ QString value = resultItem.data( (*it) );
// odebug << "Reading " << (*it) << "... found: " << value << "" << oendl;
@@ -817,15 +916,10 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co
}
- // First insert uid
- nonCustomMap.insert( Qtopia::AddressUid, resItem.data( "uid" ) );
- t3needed = t3.elapsed();
-
- // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl;
- odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed
- << " ms, mapping: " << t3needed << " ms" << oendl;
+ nonCustomMap.insert( Qtopia::AddressUid, resultItem.data( "uid" ) );
return nonCustomMap;
}
+
QMap<QString, QString> OPimContactAccessBackend_SQL::requestCustom( int uid ) const
{
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
index ba122ec..4f81735 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h
@@ -74,6 +74,5 @@ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
OPimContact find ( int uid ) const;
- // FIXME: Add lookahead-cache support !
- //OPimContact find(int uid, const QArray<int>&, uint cur, Frontend::CacheDirection )const;
+ OPimContact find( int uid, const QArray<int>&, uint cur, Frontend::CacheDirection ) const;
QArray<int> queryByExample ( const OPimContact &query, int settings,
@@ -99,4 +98,6 @@ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend {
QMap<int, QString> requestNonCustom( int uid ) const;
QMap<QString, QString> requestCustom( int uid ) const;
+ QMap<int, QString> fillNonCustomMap( const Opie::DB::OSQLResultItem& resultItem ) const;
+ OPimContact requestContactsAndCache( int uid, const QArray<int>& cachelist ) const;
void update();
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h
index 0682063..15a7b7f 100644
--- a/libopie2/opiepim/backend/opimaccessbackend.h
+++ b/libopie2/opiepim/backend/opimaccessbackend.h
@@ -97,5 +97,5 @@ public:
virtual T find(int uid, const QArray<int>& items,
- uint current, typename Frontend::CacheDirection )const ;
+ uint current, typename Frontend::CacheDirection ) const;
/**
* clear the back end
@@ -129,6 +129,14 @@ public:
protected:
int access()const;
+
void cache( const T& t )const;
+ /**
+ * Returns the element with given uid out of the cache.
+ * Returns empty element if nothing was found.
+ * <b>Attention:</b> This just works if we have a frontend which contains the cache !
+ */
+ T cacheFind( int uid ) const;
+
/**
* use a prime number here!
@@ -162,15 +170,27 @@ void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
template <class T>
void OPimAccessBackend<T>::cache( const T& t )const {
- if (m_front )
+ if ( m_front )
m_front->cache( t );
}
+
+template <class T>
+T OPimAccessBackend<T>::cacheFind( int uid )const {
+ if ( ! m_front ){
+ qWarning ( "No frontend assigned ! Therefore we cannot access the cache to return the right element!" );
+ return T();
+ }
+
+ return m_front->cacheFind( uid );
+}
+
template <class T>
void OPimAccessBackend<T>::setSaneCacheSize( int size) {
- if (m_front )
+ if ( m_front )
m_front->setSaneCacheSize( size );
}
template <class T>
T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
- uint, typename Frontend::CacheDirection )const {
+ uint, typename Frontend::CacheDirection ) const{
+ qDebug( "*** Lookahead feature not supported. Fallback to default find!" );
return find( uid );
}
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
index 55d600a..6f01b46 100644
--- a/libopie2/opiepim/core/opimaccesstemplate.h
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -36,5 +36,4 @@
#include <opie2/opimrecordlist.h>
-#include <opie2/opimcache.h>
#include <opie2/opimtemplatebase.h>
#include <opie2/odebug.h>
@@ -129,4 +128,5 @@ public:
uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const;
+
/* invalidate cache here */
/**
@@ -140,11 +140,13 @@ public:
* @return <i>true</i> if added successfully.
*/
- virtual bool add( const T& t ) ;
+ virtual bool add( const T& t ) ;
+
bool add( const OPimRecord& );
- // Needed for real generic access (eilers)
- // Info: Take this if you are working with OPimRecord, which is a generic base class, and
- // you need to add it into any database, you cannot generate a reference to
- // it and casting may be not approriate, too.
- // But take care that the accessing database is compatible to the real type of OPimRecord !!
+ /**
+ * Add an Opie PimRecord.
+ * Info: Take this if you are working with OPimRecords and you need to add it into any database.
+ * But take care that the accessing database is compatible to the real type of OPimRecord !!
+ * Otherwise this access will be rejected !
+ */
bool add( const OPimRecord* );
@@ -177,4 +179,5 @@ public:
* @internal
*/
+ virtual T cacheFind( int uid )const;
void cache( const T& )const;
void setSaneCacheSize( int );
@@ -193,4 +196,5 @@ protected:
BackEnd* backEnd();
BackEnd* m_backEnd;
+
Cache m_cache;
@@ -219,5 +223,5 @@ bool OPimAccessTemplate<T>::load() {
template <class T>
bool OPimAccessTemplate<T>::reload() {
- invalidateCache(); // zecke: I think this should be added (se)
+ invalidateCache();
return m_backEnd->reload();
}
@@ -252,8 +256,20 @@ OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime
template <class T>
T OPimAccessTemplate<T>::find( int uid ) const{
+ // First search in cache..
+ if ( m_cache.contains( uid ) )
+ return m_cache.find( uid );
+
T t = m_backEnd->find( uid );
cache( t );
+
return t;
}
+
+template <class T>
+T OPimAccessTemplate<T>::cacheFind( int uid ) const
+{
+ return m_cache.find( uid );
+}
+
template <class T>
T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
@@ -265,5 +281,5 @@ T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
*/
// owarn << "find it now " << uid << oendl;
- if (m_cache.contains( uid ) ) {
+ if ( m_cache.contains( uid ) ) {
return m_cache.find( uid );
}
@@ -285,5 +301,5 @@ bool OPimAccessTemplate<T>::add( const T& t ) {
template <class T>
-bool OPimAccessTemplate<T>::add( const OPimRecord& rec) {
+bool OPimAccessTemplate<T>::add( const OPimRecord& rec ) {
/* same type */
T tempInstance;
@@ -291,4 +307,6 @@ bool OPimAccessTemplate<T>::add( const OPimRecord& rec) {
const T& t = static_cast<const T&>(rec);
return add(t);
+ } else {
+ owarn << "Adding not possible: Objecttype mismatch" << oendl;
}
return false;
@@ -302,4 +320,6 @@ bool OPimAccessTemplate<T>::add( const OPimRecord* rec) {
const T* t = static_cast<const T*>(rec);
return add( *t );
+ } else {
+ owarn << "Adding not possible: Objecttype mismatch" << oendl;
}
return false;
diff --git a/libopie2/opiepim/core/opimtemplatebase.h b/libopie2/opiepim/core/opimtemplatebase.h
index b48dfed..ec9a94e 100644
--- a/libopie2/opiepim/core/opimtemplatebase.h
+++ b/libopie2/opiepim/core/opimtemplatebase.h
@@ -32,4 +32,5 @@
/* OPIE */
#include <opie2/opimrecord.h>
+#include <opie2/opimcache.h>
/* QT */
@@ -71,5 +72,5 @@ private:
/**
* internal template base
- * T needs to implement the copy c'tor!!!
+ * Attention: T needs to implement the copy c'tor!!!
*/
class OTemplateBasePrivate;
@@ -77,5 +78,7 @@ template <class T = OPimRecord>
class OTemplateBase : public OPimBase {
public:
+ /** Look ahead direction of cache */
enum CacheDirection { Forward=0, Reverse };
+
OTemplateBase() {
};
@@ -89,4 +92,14 @@ public:
virtual T find( int uid, const QArray<int>& items,
uint current, CacheDirection dir = Forward )const = 0;
+
+ /**
+ * Find in Cache..
+ * Returns empty object if nothing found.
+ */
+ virtual T cacheFind( int uid )const = 0;
+
+ /**
+ * Put element into Cache
+ */
virtual void cache( const T& )const = 0;
virtual void setSaneCacheSize( int ) = 0;
@@ -95,4 +108,5 @@ public:
OPimRecord* record(int uid )const;
static T* rec();
+
private: