summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/core
Side-by-side diff
Diffstat (limited to 'libopie2/opiepim/core') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h57
-rw-r--r--libopie2/opiepim/core/opimcache.h117
-rw-r--r--libopie2/opiepim/core/otemplatebase.h11
3 files changed, 182 insertions, 3 deletions
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
@@ -4,12 +4,13 @@
#include <qarray.h>
#include <opie/opimrecord.h>
#include <opie/opimaccessbackend.h>
#include <opie/orecordlist.h>
+#include "opimcache.h"
#include "otemplatebase.h"
/**
* Thats the frontend to our OPIE PIM
* Library. Either you want to use it's
* interface or you want to implement
@@ -20,12 +21,13 @@
template <class T = OPimRecord >
class OPimAccessTemplate : public OTemplateBase<T> {
public:
typedef ORecordList<T> List;
typedef OPimAccessBackend<T> BackEnd;
+ typedef OPimCache<T> Cache;
/**
* our sort order
* should be safe explaining
*/
enum SortOrder { WildCards = 0, IgnoreCase = 1,
@@ -70,12 +72,18 @@ public:
/**
* find the OPimRecord uid
*/
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
*/
virtual void clear() ;
@@ -96,40 +104,49 @@ public:
virtual bool remove( int uid );
/**
* replace T from backend
*/
virtual bool replace( const T& t) ;
+
+ /**
+ * @internal
+ */
+ void cache( const T& )const;
+ void setSaneCacheSize( int );
protected:
/**
* invalidate the cache
*/
void invalidateCache();
void setBackEnd( BackEnd* end );
/**
* returns the backend
*/
BackEnd* backEnd();
BackEnd* m_backEnd;
+ Cache m_cache;
};
template <class T>
OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
: OTemplateBase<T>(), m_backEnd( end )
{
-
+ if (end )
+ end->setFrontend( this );
}
template <class T>
OPimAccessTemplate<T>::~OPimAccessTemplate() {
qWarning("~OPimAccessTemplate<T>");
delete m_backEnd;
}
template <class T>
bool OPimAccessTemplate<T>::load() {
+ invalidateCache();
return m_backEnd->load();
}
template <class T>
bool OPimAccessTemplate<T>::reload() {
return m_backEnd->reload();
}
@@ -151,46 +168,80 @@ OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) {
List lis(ints, this );
return lis;
}
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>
void OPimAccessTemplate<T>::clear() {
invalidateCache();
m_backEnd->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() {
return m_backEnd;
}
template <class T>
bool OPimAccessTemplate<T>::wasChangedExternally()const {
return false;
}
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,21 +1,32 @@
#ifndef OPIE_TEMPLATE_BASE_H
#define OPIE_TEMPLATE_BASE_H
+#include <qarray.h>
+
#include "opimrecord.h"
/**
* internal template base
*/
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;
+
};
#endif