summaryrefslogtreecommitdiff
path: root/libopie2/opiepim
Side-by-side diff
Diffstat (limited to 'libopie2/opiepim') (more/less context) (show 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
@@ -17,4 +17,11 @@
* 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.
@@ -29,6 +36,6 @@
* =====================================================================
*/
-#ifndef __OPIE_BACKENDFACTORY_H_
-#define __OPIE_BACKENDFACTORY_H_
+#ifndef OPIE_BACKENDFACTORY_H_
+#define OPIE_BACKENDFACTORY_H_
#include <qstring.h>
@@ -39,7 +46,8 @@
#include "ocontactaccessbackend_xml.h"
-#ifdef __USE_SQL
+/*#ifdef __USE_SQL
#include "otodoaccesssql.h"
#endif
+*/
template<class T>
@@ -73,11 +81,11 @@ 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 );
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
@@ -4,4 +4,5 @@
#include <qarray.h>
+#include <opie/otemplatebase.h>
#include <opie/opimrecord.h>
@@ -18,4 +19,5 @@ template <class T = OPimRecord>
class OPimAccessBackend {
public:
+ typedef OTemplateBase<T> Frontend;
OPimAccessBackend();
virtual ~OPimAccessBackend();
@@ -55,4 +57,6 @@ 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
@@ -75,4 +79,19 @@ 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;
};
@@ -80,5 +99,5 @@ public:
template <class T>
OPimAccessBackend<T>::OPimAccessBackend() {
-
+ m_front = 0l;
}
template <class T>
@@ -86,4 +105,23 @@ 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
@@ -8,4 +8,5 @@
#include <opie/orecordlist.h>
+#include "opimcache.h"
#include "otemplatebase.h"
@@ -24,4 +25,5 @@ public:
typedef ORecordList<T> List;
typedef OPimAccessBackend<T> BackEnd;
+ typedef OPimCache<T> Cache;
/**
@@ -74,4 +76,10 @@ 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 */
/**
@@ -100,4 +108,10 @@ public:
*/
virtual bool replace( const T& t) ;
+
+ /**
+ * @internal
+ */
+ void cache( const T& )const;
+ void setSaneCacheSize( int );
protected:
/**
@@ -112,4 +126,5 @@ protected:
BackEnd* backEnd();
BackEnd* m_backEnd;
+ Cache m_cache;
};
@@ -119,5 +134,6 @@ OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
: OTemplateBase<T>(), m_backEnd( end )
{
-
+ if (end )
+ end->setFrontend( this );
}
template <class T>
@@ -128,4 +144,5 @@ OPimAccessTemplate<T>::~OPimAccessTemplate() {
template <class T>
bool OPimAccessTemplate<T>::load() {
+ invalidateCache();
return m_backEnd->load();
}
@@ -155,4 +172,24 @@ 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;
}
@@ -164,21 +201,24 @@ 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>
@@ -193,4 +233,15 @@ 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
@@ -2,4 +2,6 @@
#define OPIE_TEMPLATE_BASE_H
+#include <qarray.h>
+
#include "opimrecord.h"
@@ -10,4 +12,5 @@ template <class T = OPimRecord>
class OTemplateBase {
public:
+ enum CacheDirection { Forward=0, Reverse };
OTemplateBase() {
};
@@ -16,4 +19,12 @@ public:
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
@@ -69,4 +69,5 @@ private:
bool m_end : 1;
T m_record;
+ bool m_direction :1;
/* d pointer for future versions */
@@ -126,4 +127,6 @@ ORecordListIterator<T>::ORecordListIterator() {
m_end = true;
m_record = T();
+ /* forward */
+ m_direction = TRUE;
}
template <class T>
@@ -140,4 +143,5 @@ ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) {
m_end = it.m_end;
m_record = it.m_record;
+ m_direction = it.m_direction;
}
@@ -157,9 +161,7 @@ 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();
@@ -170,4 +172,5 @@ T ORecordListIterator<T>::operator*() {
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
+ m_direction = true;
if (m_current < m_uids.count() ) {
m_end = false;
@@ -180,4 +183,5 @@ ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
template <class T>
ORecordListIterator<T> &ORecordListIterator<T>::operator--() {
+ m_direction = false;
if ( m_current > 0 ) {
--m_current;
@@ -208,5 +212,6 @@ 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 )
{
}
@@ -255,5 +260,6 @@ 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