summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-10 17:08:58 (UTC)
committer zecke <zecke>2002-10-10 17:08:58 (UTC)
commit1dcc1b1fc9fd35d959255452c8b5be1269ca4f44 (patch) (unidiff)
tree469d239dec74f5751f3aced43c4bae1f0f3a42e3
parentaa38f642a07810515dcc18ea38bf520e26d7f88e (diff)
downloadopie-1dcc1b1fc9fd35d959255452c8b5be1269ca4f44.zip
opie-1dcc1b1fc9fd35d959255452c8b5be1269ca4f44.tar.gz
opie-1dcc1b1fc9fd35d959255452c8b5be1269ca4f44.tar.bz2
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
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie/pim/obackendfactory.h20
-rw-r--r--libopie/pim/opimaccessbackend.h40
-rw-r--r--libopie/pim/opimaccesstemplate.h57
-rw-r--r--libopie/pim/opimcache.h117
-rw-r--r--libopie/pim/orecordlist.h20
-rw-r--r--libopie/pim/otemplatebase.h11
-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
12 files changed, 496 insertions, 34 deletions
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h
index f11f029..89b8c58 100644
--- a/libopie/pim/obackendfactory.h
+++ b/libopie/pim/obackendfactory.h
@@ -16,6 +16,13 @@
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.3 2002/10/10 17:08:58 zecke
20 * The Cache is finally in place
21 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
22 * 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....
23 * I still have to fully implement read ahead
24 * This change is bic but sc
25 *
19 * Revision 1.2 2002/10/08 09:27:36 eilers 26 * Revision 1.2 2002/10/08 09:27:36 eilers
20 * Fixed libopie.pro to include the new pim-API. 27 * Fixed libopie.pro to include the new pim-API.
21 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to 28 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
@@ -28,8 +35,8 @@
28 * 35 *
29 * ===================================================================== 36 * =====================================================================
30 */ 37 */
31#ifndef __OPIE_BACKENDFACTORY_H_ 38#ifndef OPIE_BACKENDFACTORY_H_
32#define __OPIE_BACKENDFACTORY_H_ 39#define OPIE_BACKENDFACTORY_H_
33 40
34#include <qstring.h> 41#include <qstring.h>
35#include <qasciidict.h> 42#include <qasciidict.h>
@@ -38,9 +45,10 @@
38#include "otodoaccessxml.h" 45#include "otodoaccessxml.h"
39#include "ocontactaccessbackend_xml.h" 46#include "ocontactaccessbackend_xml.h"
40 47
41#ifdef __USE_SQL 48/*#ifdef __USE_SQL
42#include "otodoaccesssql.h" 49#include "otodoaccesssql.h"
43#endif 50#endif
51*/
44 52
45template<class T> 53template<class T>
46class OBackendFactory 54class OBackendFactory
@@ -72,13 +80,13 @@ class OBackendFactory
72 80
73 switch ( *dict.take( backendName ) ){ 81 switch ( *dict.take( backendName ) ){
74 case TODO: 82 case TODO:
75#ifdef __USE_SQL 83/*#ifdef __USE_SQL
76 if ( backend == "sql" ) 84 if ( backend == "sql" )
77 return (T*) new OTodoAccessBackendSQL(""); 85 return (T*) new OTodoAccessBackendSQL("");
78#else 86#else*/
79 if ( backend == "sql" ) 87 if ( backend == "sql" )
80 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 88 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
81#endif 89//#endif
82 90
83 return (T*) new OTodoAccessXML( appName ); 91 return (T*) new OTodoAccessXML( appName );
84 case CONTACT: 92 case CONTACT:
diff --git a/libopie/pim/opimaccessbackend.h b/libopie/pim/opimaccessbackend.h
index c27acbb..27d3cb8 100644
--- a/libopie/pim/opimaccessbackend.h
+++ b/libopie/pim/opimaccessbackend.h
@@ -3,6 +3,7 @@
3 3
4#include <qarray.h> 4#include <qarray.h>
5 5
6#include <opie/otemplatebase.h>
6#include <opie/opimrecord.h> 7#include <opie/opimrecord.h>
7 8
8 9
@@ -17,6 +18,7 @@
17template <class T = OPimRecord> 18template <class T = OPimRecord>
18class OPimAccessBackend { 19class OPimAccessBackend {
19public: 20public:
21 typedef OTemplateBase<T> Frontend;
20 OPimAccessBackend(); 22 OPimAccessBackend();
21 virtual ~OPimAccessBackend(); 23 virtual ~OPimAccessBackend();
22 24
@@ -54,6 +56,8 @@ public:
54 */ 56 */
55 virtual T find(int uid )const = 0; 57 virtual T find(int uid )const = 0;
56 58
59 virtual T find(int uid, const QArray<int>& items,
60 uint current, Frontend::CacheDirection )const ;
57 /** 61 /**
58 * clear the back end 62 * clear the back end
59 */ 63 */
@@ -74,16 +78,50 @@ public:
74 */ 78 */
75 virtual bool replace( const T& t ) = 0; 79 virtual bool replace( const T& t ) = 0;
76 80
81 /*
82 * setTheFrontEnd!!!
83 */
84 void setFrontend( Frontend* front );
85
86protected:
87 void cache( const T& t )const;
88
89 /**
90 * use a prime number here!
91 */
92 void setSaneCacheSize( int );
93
94private:
95 Frontend* m_front;
77 96
78}; 97};
79 98
80template <class T> 99template <class T>
81OPimAccessBackend<T>::OPimAccessBackend() { 100OPimAccessBackend<T>::OPimAccessBackend() {
82 101 m_front = 0l;
83} 102}
84template <class T> 103template <class T>
85OPimAccessBackend<T>::~OPimAccessBackend() { 104OPimAccessBackend<T>::~OPimAccessBackend() {
86 105
87} 106}
107template <class T>
108void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
109 m_front = fr;
110}
111template <class T>
112void OPimAccessBackend<T>::cache( const T& t )const {
113 if (m_front )
114 m_front->cache( t );
115}
116template <class T>
117void OPimAccessBackend<T>::setSaneCacheSize( int size) {
118 if (m_front )
119 m_front->setSaneCacheSize( size );
120}
121template <class T>
122T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
123 uint, Frontend::CacheDirection )const {
124 return find( uid );
125}
88 126
89#endif 127#endif
diff --git a/libopie/pim/opimaccesstemplate.h b/libopie/pim/opimaccesstemplate.h
index 31ab516..92d7192 100644
--- a/libopie/pim/opimaccesstemplate.h
+++ b/libopie/pim/opimaccesstemplate.h
@@ -7,6 +7,7 @@
7#include <opie/opimaccessbackend.h> 7#include <opie/opimaccessbackend.h>
8#include <opie/orecordlist.h> 8#include <opie/orecordlist.h>
9 9
10#include "opimcache.h"
10#include "otemplatebase.h" 11#include "otemplatebase.h"
11 12
12/** 13/**
@@ -23,6 +24,7 @@ class OPimAccessTemplate : public OTemplateBase<T> {
23public: 24public:
24 typedef ORecordList<T> List; 25 typedef ORecordList<T> List;
25 typedef OPimAccessBackend<T> BackEnd; 26 typedef OPimAccessBackend<T> BackEnd;
27 typedef OPimCache<T> Cache;
26 28
27 /** 29 /**
28 * our sort order 30 * our sort order
@@ -73,6 +75,12 @@ public:
73 */ 75 */
74 virtual T find( int uid )const; 76 virtual T find( int uid )const;
75 77
78 /**
79 * read ahead cache find method ;)
80 */
81 virtual T find( int uid, const QArray<int>&,
82 uint current, CacheDirection dir = Forward )const;
83
76 /* invalidate cache here */ 84 /* invalidate cache here */
77 /** 85 /**
78 * clears the backend and invalidates the backend 86 * clears the backend and invalidates the backend
@@ -99,6 +107,12 @@ public:
99 * replace T from backend 107 * replace T from backend
100 */ 108 */
101 virtual bool replace( const T& t) ; 109 virtual bool replace( const T& t) ;
110
111 /**
112 * @internal
113 */
114 void cache( const T& )const;
115 void setSaneCacheSize( int );
102protected: 116protected:
103 /** 117 /**
104 * invalidate the cache 118 * invalidate the cache
@@ -111,6 +125,7 @@ protected:
111 */ 125 */
112 BackEnd* backEnd(); 126 BackEnd* backEnd();
113 BackEnd* m_backEnd; 127 BackEnd* m_backEnd;
128 Cache m_cache;
114 129
115}; 130};
116 131
@@ -118,7 +133,8 @@ template <class T>
118OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) 133OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
119 : OTemplateBase<T>(), m_backEnd( end ) 134 : OTemplateBase<T>(), m_backEnd( end )
120{ 135{
121 136 if (end )
137 end->setFrontend( this );
122} 138}
123template <class T> 139template <class T>
124OPimAccessTemplate<T>::~OPimAccessTemplate() { 140OPimAccessTemplate<T>::~OPimAccessTemplate() {
@@ -127,6 +143,7 @@ OPimAccessTemplate<T>::~OPimAccessTemplate() {
127} 143}
128template <class T> 144template <class T>
129bool OPimAccessTemplate<T>::load() { 145bool OPimAccessTemplate<T>::load() {
146 invalidateCache();
130 return m_backEnd->load(); 147 return m_backEnd->load();
131} 148}
132template <class T> 149template <class T>
@@ -154,6 +171,26 @@ OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) {
154template <class T> 171template <class T>
155T OPimAccessTemplate<T>::find( int uid ) const{ 172T OPimAccessTemplate<T>::find( int uid ) const{
156 T t = m_backEnd->find( uid ); 173 T t = m_backEnd->find( uid );
174 cache( t );
175 return t;
176}
177template <class T>
178T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
179 uint current, CacheDirection dir )const {
180 /*
181 * better do T.isEmpty()
182 * after a find this way we would
183 * avoid two finds in QCache...
184 */
185 // qWarning("find it now %d", uid );
186 if (m_cache.contains( uid ) ) {
187 qWarning("m cache contains %d", uid);
188 return m_cache.find( uid );
189 }
190
191 T t = m_backEnd->find( uid, ar, current, dir );
192 qWarning("found it and cache it now %d", uid);
193 cache( t );
157 return t; 194 return t;
158} 195}
159template <class T> 196template <class T>
@@ -163,23 +200,26 @@ void OPimAccessTemplate<T>::clear() {
163} 200}
164template <class T> 201template <class T>
165bool OPimAccessTemplate<T>::add( const T& t ) { 202bool OPimAccessTemplate<T>::add( const T& t ) {
203 cache( t );
166 return m_backEnd->add( t ); 204 return m_backEnd->add( t );
167} 205}
168template <class T> 206template <class T>
169bool OPimAccessTemplate<T>::remove( const T& t ) { 207bool OPimAccessTemplate<T>::remove( const T& t ) {
170 return m_backEnd->remove( t.uid() ); 208 return remove( t.uid() );
171} 209}
172template <class T> 210template <class T>
173bool OPimAccessTemplate<T>::remove( int uid ) { 211bool OPimAccessTemplate<T>::remove( int uid ) {
212 m_cache.remove( uid );
174 return m_backEnd->remove( uid ); 213 return m_backEnd->remove( uid );
175} 214}
176template <class T> 215template <class T>
177bool OPimAccessTemplate<T>::replace( const T& t ) { 216bool OPimAccessTemplate<T>::replace( const T& t ) {
217 m_cache.replace( t );
178 return m_backEnd->replace( t ); 218 return m_backEnd->replace( t );
179} 219}
180template <class T> 220template <class T>
181void OPimAccessTemplate<T>::invalidateCache() { 221void OPimAccessTemplate<T>::invalidateCache() {
182 222 m_cache.invalidate();
183} 223}
184template <class T> 224template <class T>
185OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() { 225OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() {
@@ -192,5 +232,16 @@ bool OPimAccessTemplate<T>::wasChangedExternally()const {
192template <class T> 232template <class T>
193void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) { 233void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) {
194 m_backEnd = end; 234 m_backEnd = end;
235 if (m_backEnd )
236 m_backEnd->setFrontend( this );
237}
238template <class T>
239void OPimAccessTemplate<T>::cache( const T& t ) const{
240 /* hacky we need to work around the const*/
241 ((OPimAccessTemplate<T>*)this)->m_cache.add( t );
242}
243template <class T>
244void OPimAccessTemplate<T>::setSaneCacheSize( int size ) {
245 m_cache.setSize( size );
195} 246}
196#endif 247#endif
diff --git a/libopie/pim/opimcache.h b/libopie/pim/opimcache.h
new file mode 100644
index 0000000..067f6e7
--- a/dev/null
+++ b/libopie/pim/opimcache.h
@@ -0,0 +1,117 @@
1#ifndef OPIE_PIM_CACHE_H
2#define OPIE_PIM_CACHE_H
3
4#include <qintcache.h>
5
6#include "opimrecord.h"
7
8template <class T = OPimRecord>
9class OPimCacheItem {
10public:
11 OPimCacheItem( const T& t = T() );
12 ~OPimCacheItem();
13
14 T record()const;
15 void setRecord( const T& );
16private:
17 T m_t;
18};
19
20/**
21 * OPimCache for caching the items
22 * We support adding, removing
23 * and finding
24 */
25template <class T = OPimRecord>
26class OPimCache {
27public:
28 typedef OPimCacheItem<T> Item;
29 OPimCache();
30 ~OPimCache();
31
32 bool contains(int uid)const;
33 void invalidate();
34 void setSize( int size );
35
36 T find(int uid )const;
37 void add( const T& );
38 void remove( int uid );
39 void replace( const T& );
40
41private:
42 QIntCache<Item> m_cache;
43};
44
45// Implementation
46template <class T>
47OPimCacheItem<T>::OPimCacheItem( const T& t )
48 : m_t(t) {
49}
50template <class T>
51OPimCacheItem<T>::~OPimCacheItem() {
52
53}
54template <class T>
55T OPimCacheItem<T>::record()const {
56 return m_t;
57}
58template <class T>
59void OPimCacheItem<T>::setRecord( const T& t ) {
60 m_t = t;
61}
62// Cache
63template <class T>
64OPimCache<T>::OPimCache() {
65 m_cache.setAutoDelete( TRUE );
66}
67template <class T>
68OPimCache<T>::~OPimCache() {
69
70}
71template <class T>
72bool OPimCache<T>::contains(int uid )const {
73 Item* it = m_cache.find( uid, FALSE );
74 if (!it)
75 return false;
76 return true;
77}
78template <class T>
79void OPimCache<T>::invalidate() {
80 m_cache.clear();
81}
82template <class T>
83void OPimCache<T>::setSize( int size ) {
84 m_cache.setMaxCost( size );
85}
86template <class T>
87T OPimCache<T>::find(int uid )const {
88 Item *it = m_cache.find( uid );
89 if (it)
90 return it->record();
91 return T();
92}
93template <class T>
94void OPimCache<T>::add( const T& t ) {
95 Item* it = 0l;
96 it = m_cache.find(t.uid(), FALSE );
97
98 if (it )
99 it->setRecord( t );
100
101 it = new Item( t );
102 if (!m_cache.insert( t.uid(), it ) )
103 delete it;
104}
105template <class T>
106void OPimCache<T>::remove( int uid ) {
107 m_cache.remove( uid );
108}
109template <class T>
110void OPimCache<T>::replace( const T& t) {
111 Item *it = m_cache.find( t.uid() );
112 if ( it ) {
113 it->setRecord( t );
114 }
115}
116
117#endif
diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h
index b6fa7fa..08f5c85 100644
--- a/libopie/pim/orecordlist.h
+++ b/libopie/pim/orecordlist.h
@@ -68,6 +68,7 @@ private:
68 const Base* m_temp; 68 const Base* m_temp;
69 bool m_end : 1; 69 bool m_end : 1;
70 T m_record; 70 T m_record;
71 bool m_direction :1;
71 72
72 /* d pointer for future versions */ 73 /* d pointer for future versions */
73 class IteratorPrivate; 74 class IteratorPrivate;
@@ -125,6 +126,8 @@ ORecordListIterator<T>::ORecordListIterator() {
125 m_temp = 0l; 126 m_temp = 0l;
126 m_end = true; 127 m_end = true;
127 m_record = T(); 128 m_record = T();
129 /* forward */
130 m_direction = TRUE;
128} 131}
129template <class T> 132template <class T>
130ORecordListIterator<T>::~ORecordListIterator() { 133ORecordListIterator<T>::~ORecordListIterator() {
@@ -139,6 +142,7 @@ ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) {
139 m_temp = it.m_temp; 142 m_temp = it.m_temp;
140 m_end = it.m_end; 143 m_end = it.m_end;
141 m_record = it.m_record; 144 m_record = it.m_record;
145 m_direction = it.m_direction;
142} 146}
143 147
144template <class T> 148template <class T>
@@ -156,11 +160,9 @@ template <class T>
156T ORecordListIterator<T>::operator*() { 160T ORecordListIterator<T>::operator*() {
157 qWarning("operator* %d %d", m_current, m_uids[m_current] ); 161 qWarning("operator* %d %d", m_current, m_uids[m_current] );
158 if (!m_end ) 162 if (!m_end )
159 /* FIXME 163 m_record = m_temp->find( m_uids[m_current], m_uids, m_current,
160 * until the cache is in place 164 m_direction ? Base::Forward :
161 * we do the uid match uid check 165 Base::Reverse );
162 */
163 m_record = m_temp->find( m_uids[m_current] );
164 else 166 else
165 m_record = T(); 167 m_record = T();
166 168
@@ -169,6 +171,7 @@ T ORecordListIterator<T>::operator*() {
169 171
170template <class T> 172template <class T>
171ORecordListIterator<T> &ORecordListIterator<T>::operator++() { 173ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
174 m_direction = true;
172 if (m_current < m_uids.count() ) { 175 if (m_current < m_uids.count() ) {
173 m_end = false; 176 m_end = false;
174 ++m_current; 177 ++m_current;
@@ -179,6 +182,7 @@ ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
179} 182}
180template <class T> 183template <class T>
181ORecordListIterator<T> &ORecordListIterator<T>::operator--() { 184ORecordListIterator<T> &ORecordListIterator<T>::operator--() {
185 m_direction = false;
182 if ( m_current > 0 ) { 186 if ( m_current > 0 ) {
183 --m_current; 187 --m_current;
184 m_end = false; 188 m_end = false;
@@ -207,7 +211,8 @@ bool ORecordListIterator<T>::operator!=( const ORecordListIterator<T>& it ) {
207template <class T> 211template <class T>
208ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids, 212ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids,
209 const Base* t ) 213 const Base* t )
210 : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ) 214 : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ),
215 m_direction( false )
211{ 216{
212} 217}
213template <class T> 218template <class T>
@@ -254,6 +259,7 @@ return m_ids.count();
254} 259}
255template <class T> 260template <class T>
256T ORecordList<T>::operator[]( uint i ) { 261T ORecordList<T>::operator[]( uint i ) {
257 return m_acc->find( m_ids[i] ); 262 /* forward */
263 return m_acc->find( m_ids[i], m_ids, i );
258} 264}
259#endif 265#endif
diff --git a/libopie/pim/otemplatebase.h b/libopie/pim/otemplatebase.h
index f71417b..b855919 100644
--- a/libopie/pim/otemplatebase.h
+++ b/libopie/pim/otemplatebase.h
@@ -1,6 +1,8 @@
1#ifndef OPIE_TEMPLATE_BASE_H 1#ifndef OPIE_TEMPLATE_BASE_H
2#define OPIE_TEMPLATE_BASE_H 2#define OPIE_TEMPLATE_BASE_H
3 3
4#include <qarray.h>
5
4#include "opimrecord.h" 6#include "opimrecord.h"
5 7
6/** 8/**
@@ -9,12 +11,21 @@
9template <class T = OPimRecord> 11template <class T = OPimRecord>
10class OTemplateBase { 12class OTemplateBase {
11public: 13public:
14 enum CacheDirection { Forward=0, Reverse };
12 OTemplateBase() { 15 OTemplateBase() {
13 }; 16 };
14 virtual ~OTemplateBase() { 17 virtual ~OTemplateBase() {
15 } 18 }
16 virtual T find( int uid )const = 0; 19 virtual T find( int uid )const = 0;
17 20
21 /**
22 * read ahead find
23 */
24 virtual T find( int uid, const QArray<int>& items,
25 uint current, CacheDirection dir = Forward )const = 0;
26 virtual void cache( const T& )const = 0;
27 virtual void setSaneCacheSize( int ) = 0;
28
18}; 29};
19 30
20 31
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 @@
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.3 2002/10/10 17:08:58 zecke
20 * The Cache is finally in place
21 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
22 * 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....
23 * I still have to fully implement read ahead
24 * This change is bic but sc
25 *
19 * Revision 1.2 2002/10/08 09:27:36 eilers 26 * Revision 1.2 2002/10/08 09:27:36 eilers
20 * Fixed libopie.pro to include the new pim-API. 27 * Fixed libopie.pro to include the new pim-API.
21 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to 28 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
@@ -28,8 +35,8 @@
28 * 35 *
29 * ===================================================================== 36 * =====================================================================
30 */ 37 */
31#ifndef __OPIE_BACKENDFACTORY_H_ 38#ifndef OPIE_BACKENDFACTORY_H_
32#define __OPIE_BACKENDFACTORY_H_ 39#define OPIE_BACKENDFACTORY_H_
33 40
34#include <qstring.h> 41#include <qstring.h>
35#include <qasciidict.h> 42#include <qasciidict.h>
@@ -38,9 +45,10 @@
38#include "otodoaccessxml.h" 45#include "otodoaccessxml.h"
39#include "ocontactaccessbackend_xml.h" 46#include "ocontactaccessbackend_xml.h"
40 47
41#ifdef __USE_SQL 48/*#ifdef __USE_SQL
42#include "otodoaccesssql.h" 49#include "otodoaccesssql.h"
43#endif 50#endif
51*/
44 52
45template<class T> 53template<class T>
46class OBackendFactory 54class OBackendFactory
@@ -72,13 +80,13 @@ class OBackendFactory
72 80
73 switch ( *dict.take( backendName ) ){ 81 switch ( *dict.take( backendName ) ){
74 case TODO: 82 case TODO:
75#ifdef __USE_SQL 83/*#ifdef __USE_SQL
76 if ( backend == "sql" ) 84 if ( backend == "sql" )
77 return (T*) new OTodoAccessBackendSQL(""); 85 return (T*) new OTodoAccessBackendSQL("");
78#else 86#else*/
79 if ( backend == "sql" ) 87 if ( backend == "sql" )
80 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 88 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
81#endif 89//#endif
82 90
83 return (T*) new OTodoAccessXML( appName ); 91 return (T*) new OTodoAccessXML( appName );
84 case CONTACT: 92 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 @@
3 3
4#include <qarray.h> 4#include <qarray.h>
5 5
6#include <opie/otemplatebase.h>
6#include <opie/opimrecord.h> 7#include <opie/opimrecord.h>
7 8
8 9
@@ -17,6 +18,7 @@
17template <class T = OPimRecord> 18template <class T = OPimRecord>
18class OPimAccessBackend { 19class OPimAccessBackend {
19public: 20public:
21 typedef OTemplateBase<T> Frontend;
20 OPimAccessBackend(); 22 OPimAccessBackend();
21 virtual ~OPimAccessBackend(); 23 virtual ~OPimAccessBackend();
22 24
@@ -54,6 +56,8 @@ public:
54 */ 56 */
55 virtual T find(int uid )const = 0; 57 virtual T find(int uid )const = 0;
56 58
59 virtual T find(int uid, const QArray<int>& items,
60 uint current, Frontend::CacheDirection )const ;
57 /** 61 /**
58 * clear the back end 62 * clear the back end
59 */ 63 */
@@ -74,16 +78,50 @@ public:
74 */ 78 */
75 virtual bool replace( const T& t ) = 0; 79 virtual bool replace( const T& t ) = 0;
76 80
81 /*
82 * setTheFrontEnd!!!
83 */
84 void setFrontend( Frontend* front );
85
86protected:
87 void cache( const T& t )const;
88
89 /**
90 * use a prime number here!
91 */
92 void setSaneCacheSize( int );
93
94private:
95 Frontend* m_front;
77 96
78}; 97};
79 98
80template <class T> 99template <class T>
81OPimAccessBackend<T>::OPimAccessBackend() { 100OPimAccessBackend<T>::OPimAccessBackend() {
82 101 m_front = 0l;
83} 102}
84template <class T> 103template <class T>
85OPimAccessBackend<T>::~OPimAccessBackend() { 104OPimAccessBackend<T>::~OPimAccessBackend() {
86 105
87} 106}
107template <class T>
108void OPimAccessBackend<T>::setFrontend( Frontend* fr ) {
109 m_front = fr;
110}
111template <class T>
112void OPimAccessBackend<T>::cache( const T& t )const {
113 if (m_front )
114 m_front->cache( t );
115}
116template <class T>
117void OPimAccessBackend<T>::setSaneCacheSize( int size) {
118 if (m_front )
119 m_front->setSaneCacheSize( size );
120}
121template <class T>
122T OPimAccessBackend<T>::find( int uid, const QArray<int>&,
123 uint, Frontend::CacheDirection )const {
124 return find( uid );
125}
88 126
89#endif 127#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 @@
7#include <opie/opimaccessbackend.h> 7#include <opie/opimaccessbackend.h>
8#include <opie/orecordlist.h> 8#include <opie/orecordlist.h>
9 9
10#include "opimcache.h"
10#include "otemplatebase.h" 11#include "otemplatebase.h"
11 12
12/** 13/**
@@ -23,6 +24,7 @@ class OPimAccessTemplate : public OTemplateBase<T> {
23public: 24public:
24 typedef ORecordList<T> List; 25 typedef ORecordList<T> List;
25 typedef OPimAccessBackend<T> BackEnd; 26 typedef OPimAccessBackend<T> BackEnd;
27 typedef OPimCache<T> Cache;
26 28
27 /** 29 /**
28 * our sort order 30 * our sort order
@@ -73,6 +75,12 @@ public:
73 */ 75 */
74 virtual T find( int uid )const; 76 virtual T find( int uid )const;
75 77
78 /**
79 * read ahead cache find method ;)
80 */
81 virtual T find( int uid, const QArray<int>&,
82 uint current, CacheDirection dir = Forward )const;
83
76 /* invalidate cache here */ 84 /* invalidate cache here */
77 /** 85 /**
78 * clears the backend and invalidates the backend 86 * clears the backend and invalidates the backend
@@ -99,6 +107,12 @@ public:
99 * replace T from backend 107 * replace T from backend
100 */ 108 */
101 virtual bool replace( const T& t) ; 109 virtual bool replace( const T& t) ;
110
111 /**
112 * @internal
113 */
114 void cache( const T& )const;
115 void setSaneCacheSize( int );
102protected: 116protected:
103 /** 117 /**
104 * invalidate the cache 118 * invalidate the cache
@@ -111,6 +125,7 @@ protected:
111 */ 125 */
112 BackEnd* backEnd(); 126 BackEnd* backEnd();
113 BackEnd* m_backEnd; 127 BackEnd* m_backEnd;
128 Cache m_cache;
114 129
115}; 130};
116 131
@@ -118,7 +133,8 @@ template <class T>
118OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) 133OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
119 : OTemplateBase<T>(), m_backEnd( end ) 134 : OTemplateBase<T>(), m_backEnd( end )
120{ 135{
121 136 if (end )
137 end->setFrontend( this );
122} 138}
123template <class T> 139template <class T>
124OPimAccessTemplate<T>::~OPimAccessTemplate() { 140OPimAccessTemplate<T>::~OPimAccessTemplate() {
@@ -127,6 +143,7 @@ OPimAccessTemplate<T>::~OPimAccessTemplate() {
127} 143}
128template <class T> 144template <class T>
129bool OPimAccessTemplate<T>::load() { 145bool OPimAccessTemplate<T>::load() {
146 invalidateCache();
130 return m_backEnd->load(); 147 return m_backEnd->load();
131} 148}
132template <class T> 149template <class T>
@@ -154,6 +171,26 @@ OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) {
154template <class T> 171template <class T>
155T OPimAccessTemplate<T>::find( int uid ) const{ 172T OPimAccessTemplate<T>::find( int uid ) const{
156 T t = m_backEnd->find( uid ); 173 T t = m_backEnd->find( uid );
174 cache( t );
175 return t;
176}
177template <class T>
178T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
179 uint current, CacheDirection dir )const {
180 /*
181 * better do T.isEmpty()
182 * after a find this way we would
183 * avoid two finds in QCache...
184 */
185 // qWarning("find it now %d", uid );
186 if (m_cache.contains( uid ) ) {
187 qWarning("m cache contains %d", uid);
188 return m_cache.find( uid );
189 }
190
191 T t = m_backEnd->find( uid, ar, current, dir );
192 qWarning("found it and cache it now %d", uid);
193 cache( t );
157 return t; 194 return t;
158} 195}
159template <class T> 196template <class T>
@@ -163,23 +200,26 @@ void OPimAccessTemplate<T>::clear() {
163} 200}
164template <class T> 201template <class T>
165bool OPimAccessTemplate<T>::add( const T& t ) { 202bool OPimAccessTemplate<T>::add( const T& t ) {
203 cache( t );
166 return m_backEnd->add( t ); 204 return m_backEnd->add( t );
167} 205}
168template <class T> 206template <class T>
169bool OPimAccessTemplate<T>::remove( const T& t ) { 207bool OPimAccessTemplate<T>::remove( const T& t ) {
170 return m_backEnd->remove( t.uid() ); 208 return remove( t.uid() );
171} 209}
172template <class T> 210template <class T>
173bool OPimAccessTemplate<T>::remove( int uid ) { 211bool OPimAccessTemplate<T>::remove( int uid ) {
212 m_cache.remove( uid );
174 return m_backEnd->remove( uid ); 213 return m_backEnd->remove( uid );
175} 214}
176template <class T> 215template <class T>
177bool OPimAccessTemplate<T>::replace( const T& t ) { 216bool OPimAccessTemplate<T>::replace( const T& t ) {
217 m_cache.replace( t );
178 return m_backEnd->replace( t ); 218 return m_backEnd->replace( t );
179} 219}
180template <class T> 220template <class T>
181void OPimAccessTemplate<T>::invalidateCache() { 221void OPimAccessTemplate<T>::invalidateCache() {
182 222 m_cache.invalidate();
183} 223}
184template <class T> 224template <class T>
185OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() { 225OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() {
@@ -192,5 +232,16 @@ bool OPimAccessTemplate<T>::wasChangedExternally()const {
192template <class T> 232template <class T>
193void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) { 233void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) {
194 m_backEnd = end; 234 m_backEnd = end;
235 if (m_backEnd )
236 m_backEnd->setFrontend( this );
237}
238template <class T>
239void OPimAccessTemplate<T>::cache( const T& t ) const{
240 /* hacky we need to work around the const*/
241 ((OPimAccessTemplate<T>*)this)->m_cache.add( t );
242}
243template <class T>
244void OPimAccessTemplate<T>::setSaneCacheSize( int size ) {
245 m_cache.setSize( size );
195} 246}
196#endif 247#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 @@
1#ifndef OPIE_PIM_CACHE_H
2#define OPIE_PIM_CACHE_H
3
4#include <qintcache.h>
5
6#include "opimrecord.h"
7
8template <class T = OPimRecord>
9class OPimCacheItem {
10public:
11 OPimCacheItem( const T& t = T() );
12 ~OPimCacheItem();
13
14 T record()const;
15 void setRecord( const T& );
16private:
17 T m_t;
18};
19
20/**
21 * OPimCache for caching the items
22 * We support adding, removing
23 * and finding
24 */
25template <class T = OPimRecord>
26class OPimCache {
27public:
28 typedef OPimCacheItem<T> Item;
29 OPimCache();
30 ~OPimCache();
31
32 bool contains(int uid)const;
33 void invalidate();
34 void setSize( int size );
35
36 T find(int uid )const;
37 void add( const T& );
38 void remove( int uid );
39 void replace( const T& );
40
41private:
42 QIntCache<Item> m_cache;
43};
44
45// Implementation
46template <class T>
47OPimCacheItem<T>::OPimCacheItem( const T& t )
48 : m_t(t) {
49}
50template <class T>
51OPimCacheItem<T>::~OPimCacheItem() {
52
53}
54template <class T>
55T OPimCacheItem<T>::record()const {
56 return m_t;
57}
58template <class T>
59void OPimCacheItem<T>::setRecord( const T& t ) {
60 m_t = t;
61}
62// Cache
63template <class T>
64OPimCache<T>::OPimCache() {
65 m_cache.setAutoDelete( TRUE );
66}
67template <class T>
68OPimCache<T>::~OPimCache() {
69
70}
71template <class T>
72bool OPimCache<T>::contains(int uid )const {
73 Item* it = m_cache.find( uid, FALSE );
74 if (!it)
75 return false;
76 return true;
77}
78template <class T>
79void OPimCache<T>::invalidate() {
80 m_cache.clear();
81}
82template <class T>
83void OPimCache<T>::setSize( int size ) {
84 m_cache.setMaxCost( size );
85}
86template <class T>
87T OPimCache<T>::find(int uid )const {
88 Item *it = m_cache.find( uid );
89 if (it)
90 return it->record();
91 return T();
92}
93template <class T>
94void OPimCache<T>::add( const T& t ) {
95 Item* it = 0l;
96 it = m_cache.find(t.uid(), FALSE );
97
98 if (it )
99 it->setRecord( t );
100
101 it = new Item( t );
102 if (!m_cache.insert( t.uid(), it ) )
103 delete it;
104}
105template <class T>
106void OPimCache<T>::remove( int uid ) {
107 m_cache.remove( uid );
108}
109template <class T>
110void OPimCache<T>::replace( const T& t) {
111 Item *it = m_cache.find( t.uid() );
112 if ( it ) {
113 it->setRecord( t );
114 }
115}
116
117#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 @@
1#ifndef OPIE_TEMPLATE_BASE_H 1#ifndef OPIE_TEMPLATE_BASE_H
2#define OPIE_TEMPLATE_BASE_H 2#define OPIE_TEMPLATE_BASE_H
3 3
4#include <qarray.h>
5
4#include "opimrecord.h" 6#include "opimrecord.h"
5 7
6/** 8/**
@@ -9,12 +11,21 @@
9template <class T = OPimRecord> 11template <class T = OPimRecord>
10class OTemplateBase { 12class OTemplateBase {
11public: 13public:
14 enum CacheDirection { Forward=0, Reverse };
12 OTemplateBase() { 15 OTemplateBase() {
13 }; 16 };
14 virtual ~OTemplateBase() { 17 virtual ~OTemplateBase() {
15 } 18 }
16 virtual T find( int uid )const = 0; 19 virtual T find( int uid )const = 0;
17 20
21 /**
22 * read ahead find
23 */
24 virtual T find( int uid, const QArray<int>& items,
25 uint current, CacheDirection dir = Forward )const = 0;
26 virtual void cache( const T& )const = 0;
27 virtual void setSaneCacheSize( int ) = 0;
28
18}; 29};
19 30
20 31
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:
68 const Base* m_temp; 68 const Base* m_temp;
69 bool m_end : 1; 69 bool m_end : 1;
70 T m_record; 70 T m_record;
71 bool m_direction :1;
71 72
72 /* d pointer for future versions */ 73 /* d pointer for future versions */
73 class IteratorPrivate; 74 class IteratorPrivate;
@@ -125,6 +126,8 @@ ORecordListIterator<T>::ORecordListIterator() {
125 m_temp = 0l; 126 m_temp = 0l;
126 m_end = true; 127 m_end = true;
127 m_record = T(); 128 m_record = T();
129 /* forward */
130 m_direction = TRUE;
128} 131}
129template <class T> 132template <class T>
130ORecordListIterator<T>::~ORecordListIterator() { 133ORecordListIterator<T>::~ORecordListIterator() {
@@ -139,6 +142,7 @@ ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) {
139 m_temp = it.m_temp; 142 m_temp = it.m_temp;
140 m_end = it.m_end; 143 m_end = it.m_end;
141 m_record = it.m_record; 144 m_record = it.m_record;
145 m_direction = it.m_direction;
142} 146}
143 147
144template <class T> 148template <class T>
@@ -156,11 +160,9 @@ template <class T>
156T ORecordListIterator<T>::operator*() { 160T ORecordListIterator<T>::operator*() {
157 qWarning("operator* %d %d", m_current, m_uids[m_current] ); 161 qWarning("operator* %d %d", m_current, m_uids[m_current] );
158 if (!m_end ) 162 if (!m_end )
159 /* FIXME 163 m_record = m_temp->find( m_uids[m_current], m_uids, m_current,
160 * until the cache is in place 164 m_direction ? Base::Forward :
161 * we do the uid match uid check 165 Base::Reverse );
162 */
163 m_record = m_temp->find( m_uids[m_current] );
164 else 166 else
165 m_record = T(); 167 m_record = T();
166 168
@@ -169,6 +171,7 @@ T ORecordListIterator<T>::operator*() {
169 171
170template <class T> 172template <class T>
171ORecordListIterator<T> &ORecordListIterator<T>::operator++() { 173ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
174 m_direction = true;
172 if (m_current < m_uids.count() ) { 175 if (m_current < m_uids.count() ) {
173 m_end = false; 176 m_end = false;
174 ++m_current; 177 ++m_current;
@@ -179,6 +182,7 @@ ORecordListIterator<T> &ORecordListIterator<T>::operator++() {
179} 182}
180template <class T> 183template <class T>
181ORecordListIterator<T> &ORecordListIterator<T>::operator--() { 184ORecordListIterator<T> &ORecordListIterator<T>::operator--() {
185 m_direction = false;
182 if ( m_current > 0 ) { 186 if ( m_current > 0 ) {
183 --m_current; 187 --m_current;
184 m_end = false; 188 m_end = false;
@@ -207,7 +211,8 @@ bool ORecordListIterator<T>::operator!=( const ORecordListIterator<T>& it ) {
207template <class T> 211template <class T>
208ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids, 212ORecordListIterator<T>::ORecordListIterator( const QArray<int> uids,
209 const Base* t ) 213 const Base* t )
210 : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ) 214 : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ),
215 m_direction( false )
211{ 216{
212} 217}
213template <class T> 218template <class T>
@@ -254,6 +259,7 @@ return m_ids.count();
254} 259}
255template <class T> 260template <class T>
256T ORecordList<T>::operator[]( uint i ) { 261T ORecordList<T>::operator[]( uint i ) {
257 return m_acc->find( m_ids[i] ); 262 /* forward */
263 return m_acc->find( m_ids[i], m_ids, i );
258} 264}
259#endif 265#endif