summaryrefslogtreecommitdiff
path: root/libopie2/opiepim
Side-by-side diff
Diffstat (limited to 'libopie2/opiepim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h20
-rw-r--r--libopie2/opiepim/backend/opimaccessbackend.h40
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h57
-rw-r--r--libopie2/opiepim/core/opimcache.h117
-rw-r--r--libopie2/opiepim/core/otemplatebase.h11
-rw-r--r--libopie2/opiepim/orecordlist.h20
6 files changed, 248 insertions, 17 deletions
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h
index f11f029..89b8c58 100644
--- a/libopie2/opiepim/backend/obackendfactory.h
+++ b/libopie2/opiepim/backend/obackendfactory.h
@@ -16,6 +16,13 @@
* =====================================================================
* History:
* $Log$
+ * Revision 1.3 2002/10/10 17:08:58 zecke
+ * The Cache is finally in place
+ * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
+ * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster....
+ * I still have to fully implement read ahead
+ * This change is bic but sc
+ *
* Revision 1.2 2002/10/08 09:27:36 eilers
* Fixed libopie.pro to include the new pim-API.
* The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
@@ -28,8 +35,8 @@
*
* =====================================================================
*/
-#ifndef __OPIE_BACKENDFACTORY_H_
-#define __OPIE_BACKENDFACTORY_H_
+#ifndef OPIE_BACKENDFACTORY_H_
+#define OPIE_BACKENDFACTORY_H_
#include <qstring.h>
#include <qasciidict.h>
@@ -38,9 +45,10 @@
#include "otodoaccessxml.h"
#include "ocontactaccessbackend_xml.h"
-#ifdef __USE_SQL
+/*#ifdef __USE_SQL
#include "otodoaccesssql.h"
#endif
+*/
template<class T>
class OBackendFactory
@@ -72,13 +80,13 @@ class OBackendFactory
switch ( *dict.take( backendName ) ){
case TODO:
-#ifdef __USE_SQL
+/*#ifdef __USE_SQL
if ( backend == "sql" )
return (T*) new OTodoAccessBackendSQL("");
-#else
+#else*/
if ( backend == "sql" )
qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
-#endif
+//#endif
return (T*) new OTodoAccessXML( appName );
case CONTACT:
diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h
index c27acbb..27d3cb8 100644
--- a/libopie2/opiepim/backend/opimaccessbackend.h
+++ b/libopie2/opiepim/backend/opimaccessbackend.h
@@ -3,6 +3,7 @@
#include <qarray.h>
+#include <opie/otemplatebase.h>
#include <opie/opimrecord.h>
@@ -17,6 +18,7 @@
template <class T = OPimRecord>
class OPimAccessBackend {
public:
+ typedef OTemplateBase<T> Frontend;
OPimAccessBackend();
virtual ~OPimAccessBackend();
@@ -54,6 +56,8 @@ public:
*/
virtual T find(int uid )const = 0;
+ virtual T find(int uid, const QArray<int>& items,
+ uint current, Frontend::CacheDirection )const ;
/**
* clear the back end
*/
@@ -74,16 +78,50 @@ public:
*/
virtual bool replace( const T& t ) = 0;
+ /*
+ * setTheFrontEnd!!!
+ */
+ void setFrontend( Frontend* front );
+
+protected:
+ void cache( const T& t )const;
+
+ /**
+ * use a prime number here!
+ */
+ void setSaneCacheSize( int );
+
+private:
+ Frontend* m_front;
};
template <class T>
OPimAccessBackend<T>::OPimAccessBackend() {
-
+ m_front = 0l;
}
template <class T>
OPimAccessBackend<T>::~OPimAccessBackend() {
}
+template <class T>
+void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
+ m_front = fr;
+}
+template <class T>
+void OPimAccessBackend<T>::cache( const T& t )const {
+ if (m_front )
+ m_front->cache( t );
+}
+template <class T>
+void OPimAccessBackend<T>::setSaneCacheSize( int size) {
+ if (m_front )
+ m_front->setSaneCacheSize( size );
+}
+template <class T>
+T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
+ uint, Frontend::CacheDirection )const {
+ return find( uid );
+}
#endif
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
index 31ab516..92d7192 100644
--- a/libopie2/opiepim/core/opimaccesstemplate.h
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -7,6 +7,7 @@
#include <opie/opimaccessbackend.h>
#include <opie/orecordlist.h>
+#include "opimcache.h"
#include "otemplatebase.h"
/**
@@ -23,6 +24,7 @@ class OPimAccessTemplate : public OTemplateBase<T> {
public:
typedef ORecordList<T> List;
typedef OPimAccessBackend<T> BackEnd;
+ typedef OPimCache<T> Cache;
/**
* our sort order
@@ -73,6 +75,12 @@ public:
*/
virtual T find( int uid )const;
+ /**
+ * read ahead cache find method ;)
+ */
+ virtual T find( int uid, const QArray<int>&,
+ uint current, CacheDirection dir = Forward )const;
+
/* invalidate cache here */
/**
* clears the backend and invalidates the backend
@@ -99,6 +107,12 @@ public:
* replace T from backend
*/
virtual bool replace( const T& t) ;
+
+ /**
+ * @internal
+ */
+ void cache( const T& )const;
+ void setSaneCacheSize( int );
protected:
/**
* invalidate the cache
@@ -111,6 +125,7 @@ protected:
*/
BackEnd* backEnd();
BackEnd* m_backEnd;
+ Cache m_cache;
};
@@ -118,7 +133,8 @@ template <class T>
OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
: OTemplateBase<T>(), m_backEnd( end )
{
-
+ if (end )
+ end->setFrontend( this );
}
template <class T>
OPimAccessTemplate<T>::~OPimAccessTemplate() {
@@ -127,6 +143,7 @@ OPimAccessTemplate<T>::~OPimAccessTemplate() {
}
template <class T>
bool OPimAccessTemplate<T>::load() {
+ invalidateCache();
return m_backEnd->load();
}
template <class T>
@@ -154,6 +171,26 @@ OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) {
template <class T>
T OPimAccessTemplate<T>::find( int uid ) const{
T t = m_backEnd->find( uid );
+ cache( t );
+ return t;
+}
+template <class T>
+T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
+ uint current, CacheDirection dir )const {
+ /*
+ * better do T.isEmpty()
+ * after a find this way we would
+ * avoid two finds in QCache...
+ */
+ // qWarning("find it now %d", uid );
+ if (m_cache.contains( uid ) ) {
+ qWarning("m cache contains %d", uid);
+ return m_cache.find( uid );
+ }
+
+ T t = m_backEnd->find( uid, ar, current, dir );
+ qWarning("found it and cache it now %d", uid);
+ cache( t );
return t;
}
template <class T>
@@ -163,23 +200,26 @@ void OPimAccessTemplate<T>::clear() {
}
template <class T>
bool OPimAccessTemplate<T>::add( const T& t ) {
+ cache( t );
return m_backEnd->add( t );
}
template <class T>
bool OPimAccessTemplate<T>::remove( const T& t ) {
- return m_backEnd->remove( t.uid() );
+ return remove( t.uid() );
}
template <class T>
bool OPimAccessTemplate<T>::remove( int uid ) {
+ m_cache.remove( uid );
return m_backEnd->remove( uid );
}
template <class T>
bool OPimAccessTemplate<T>::replace( const T& t ) {
+ m_cache.replace( t );
return m_backEnd->replace( t );
}
template <class T>
void OPimAccessTemplate<T>::invalidateCache() {
-
+ m_cache.invalidate();
}
template <class T>
OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() {
@@ -192,5 +232,16 @@ bool OPimAccessTemplate<T>::wasChangedExternally()const {
template <class T>
void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) {
m_backEnd = end;
+ if (m_backEnd )
+ m_backEnd->setFrontend( this );
+}
+template <class T>
+void OPimAccessTemplate<T>::cache( const T& t ) const{
+ /* hacky we need to work around the const*/
+ ((OPimAccessTemplate<T>*)this)->m_cache.add( t );
+}
+template <class T>
+void OPimAccessTemplate<T>::setSaneCacheSize( int size ) {
+ m_cache.setSize( size );
}
#endif
diff --git a/libopie2/opiepim/core/opimcache.h b/libopie2/opiepim/core/opimcache.h
new file mode 100644
index 0000000..067f6e7
--- a/dev/null
+++ b/libopie2/opiepim/core/opimcache.h
@@ -0,0 +1,117 @@
+#ifndef OPIE_PIM_CACHE_H
+#define OPIE_PIM_CACHE_H
+
+#include <qintcache.h>
+
+#include "opimrecord.h"
+
+template <class T = OPimRecord>
+class OPimCacheItem {
+public:
+ OPimCacheItem( const T& t = T() );
+ ~OPimCacheItem();
+
+ T record()const;
+ void setRecord( const T& );
+private:
+ T m_t;
+};
+
+/**
+ * OPimCache for caching the items
+ * We support adding, removing
+ * and finding
+ */
+template <class T = OPimRecord>
+class OPimCache {
+public:
+ typedef OPimCacheItem<T> Item;
+ OPimCache();
+ ~OPimCache();
+
+ bool contains(int uid)const;
+ void invalidate();
+ void setSize( int size );
+
+ T find(int uid )const;
+ void add( const T& );
+ void remove( int uid );
+ void replace( const T& );
+
+private:
+ QIntCache<Item> m_cache;
+};
+
+// Implementation
+template <class T>
+OPimCacheItem<T>::OPimCacheItem( const T& t )
+ : m_t(t) {
+}
+template <class T>
+OPimCacheItem<T>::~OPimCacheItem() {
+
+}
+template <class T>
+T OPimCacheItem<T>::record()const {
+ return m_t;
+}
+template <class T>
+void OPimCacheItem<T>::setRecord( const T& t ) {
+ m_t = t;
+}
+// Cache
+template <class T>
+OPimCache<T>::OPimCache() {
+ m_cache.setAutoDelete( TRUE );
+}
+template <class T>
+OPimCache<T>::~OPimCache() {
+
+}
+template <class T>
+bool OPimCache<T>::contains(int uid )const {
+ Item* it = m_cache.find( uid, FALSE );
+ if (!it)
+ return false;
+ return true;
+}
+template <class T>
+void OPimCache<T>::invalidate() {
+ m_cache.clear();
+}
+template <class T>
+void OPimCache<T>::setSize( int size ) {
+ m_cache.setMaxCost( size );
+}
+template <class T>
+T OPimCache<T>::find(int uid )const {
+ Item *it = m_cache.find( uid );
+ if (it)
+ return it->record();
+ return T();
+}
+template <class T>
+void OPimCache<T>::add( const T& t ) {
+ Item* it = 0l;
+ it = m_cache.find(t.uid(), FALSE );
+
+ if (it )
+ it->setRecord( t );
+
+ it = new Item( t );
+ if (!m_cache.insert( t.uid(), it ) )
+ delete it;
+}
+template <class T>
+void OPimCache<T>::remove( int uid ) {
+ m_cache.remove( uid );
+}
+template <class T>
+void OPimCache<T>::replace( const T& t) {
+ Item *it = m_cache.find( t.uid() );
+ if ( it ) {
+ it->setRecord( t );
+ }
+}
+
+#endif
diff --git a/libopie2/opiepim/core/otemplatebase.h b/libopie2/opiepim/core/otemplatebase.h
index f71417b..b855919 100644
--- a/libopie2/opiepim/core/otemplatebase.h
+++ b/libopie2/opiepim/core/otemplatebase.h
@@ -1,6 +1,8 @@
#ifndef OPIE_TEMPLATE_BASE_H
#define OPIE_TEMPLATE_BASE_H
+#include <qarray.h>
+
#include "opimrecord.h"
/**
@@ -9,12 +11,21 @@
template <class T = OPimRecord>
class OTemplateBase {
public:
+ enum CacheDirection { Forward=0, Reverse };
OTemplateBase() {
};
virtual ~OTemplateBase() {
}
virtual T find( int uid )const = 0;
+ /**
+ * read ahead find
+ */
+ virtual T find( int uid, const QArray<int>& items,
+ uint current, CacheDirection dir = Forward )const = 0;
+ virtual void cache( const T& )const = 0;
+ virtual void setSaneCacheSize( int ) = 0;
+
};
diff --git a/libopie2/opiepim/orecordlist.h b/libopie2/opiepim/orecordlist.h
index b6fa7fa..08f5c85 100644
--- a/libopie2/opiepim/orecordlist.h
+++ b/libopie2/opiepim/orecordlist.h
@@ -68,6 +68,7 @@ private:
const Base* m_temp;
bool m_end : 1;
T m_record;
+ bool m_direction :1;
/* d pointer for future versions */
class IteratorPrivate;
@@ -125,6 +126,8 @@ ORecordListIterator<T>::ORecordListIterator() {
m_temp = 0l;
m_end = true;
m_record = T();
+ /* forward */
+ m_direction = TRUE;
}
template <class T>
ORecordListIterator<T>::~ORecordListIterator() {
@@ -139,6 +142,7 @@ ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) {
m_temp = it.m_temp;
m_end = it.m_end;
m_record = it.m_record;
+ m_direction = it.m_direction;
}
template <class T>
@@ -156,11 +160,9 @@ template <class T>
T ORecordListIterator<T>::operator*() {
qWarning("operator* %d %d", m_current, m_uids[m_current] );
if (!m_end )
- /* FIXME
- * until the cache is in place
- * we do the uid match uid check
- */
- m_record = m_temp->find( m_uids[m_current] );
+ m_record = m_temp->find( m_uids[m_current], m_uids, m_current,
+ m_direction ? Base::Forward :
+ Base::Reverse );
else
m_record = T();
@@ -169,6 +171,7 @@ T ORecordListIterator<T>::operator*() {
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
+ m_direction = true;
if (m_current < m_uids.count() ) {
m_end = false;
++m_current;
@@ -179,6 +182,7 @@ ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
}
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator--() {
+ m_direction = false;
if ( m_current > 0 ) {
--m_current;
m_end = false;
@@ -207,7 +211,8 @@ bool ORecordListIterator<T>::operator!=( const ORecordListIterator<T>& it ) {
template <class T>
ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids,
const Base* t )
- : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false )
+ : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ),
+ m_direction( false )
{
}
template <class T>
@@ -254,6 +259,7 @@ return m_ids.count();
}
template <class T>
T ORecordList<T>::operator[]( uint i ) {
- return m_acc->find( m_ids[i] );
+ /* forward */
+ return m_acc->find( m_ids[i], m_ids, i );
}
#endif