From 1dcc1b1fc9fd35d959255452c8b5be1269ca4f44 Mon Sep 17 00:00:00 2001 From: zecke Date: Thu, 10 Oct 2002 17:08:58 +0000 Subject: 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 --- (limited to 'libopie/pim') 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 @@ * ===================================================================== * 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 #include @@ -38,9 +45,10 @@ #include "otodoaccessxml.h" #include "ocontactaccessbackend_xml.h" -#ifdef __USE_SQL +/*#ifdef __USE_SQL #include "otodoaccesssql.h" #endif +*/ template 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/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 @@ #include +#include #include @@ -17,6 +18,7 @@ template class OPimAccessBackend { public: + typedef OTemplateBase Frontend; OPimAccessBackend(); virtual ~OPimAccessBackend(); @@ -54,6 +56,8 @@ public: */ virtual T find(int uid )const = 0; + virtual T find(int uid, const QArray& 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 OPimAccessBackend::OPimAccessBackend() { - + m_front = 0l; } template OPimAccessBackend::~OPimAccessBackend() { } +template +void OPimAccessBackend::setFrontend( Frontend* fr ) { + m_front = fr; +} +template +void OPimAccessBackend::cache( const T& t )const { + if (m_front ) + m_front->cache( t ); +} +template +void OPimAccessBackend::setSaneCacheSize( int size) { + if (m_front ) + m_front->setSaneCacheSize( size ); +} +template +T OPimAccessBackend::find( int uid, const QArray&, + uint, Frontend::CacheDirection )const { + return find( uid ); +} #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 @@ #include #include +#include "opimcache.h" #include "otemplatebase.h" /** @@ -23,6 +24,7 @@ class OPimAccessTemplate : public OTemplateBase { public: typedef ORecordList List; typedef OPimAccessBackend BackEnd; + typedef OPimCache 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&, + 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 OPimAccessTemplate::OPimAccessTemplate( BackEnd* end ) : OTemplateBase(), m_backEnd( end ) { - + if (end ) + end->setFrontend( this ); } template OPimAccessTemplate::~OPimAccessTemplate() { @@ -127,6 +143,7 @@ OPimAccessTemplate::~OPimAccessTemplate() { } template bool OPimAccessTemplate::load() { + invalidateCache(); return m_backEnd->load(); } template @@ -154,6 +171,26 @@ OPimAccessTemplate::queryByExample( const T& t, int sortOrder ) { template T OPimAccessTemplate::find( int uid ) const{ T t = m_backEnd->find( uid ); + cache( t ); + return t; +} +template +T OPimAccessTemplate::find( int uid, const QArray& 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 @@ -163,23 +200,26 @@ void OPimAccessTemplate::clear() { } template bool OPimAccessTemplate::add( const T& t ) { + cache( t ); return m_backEnd->add( t ); } template bool OPimAccessTemplate::remove( const T& t ) { - return m_backEnd->remove( t.uid() ); + return remove( t.uid() ); } template bool OPimAccessTemplate::remove( int uid ) { + m_cache.remove( uid ); return m_backEnd->remove( uid ); } template bool OPimAccessTemplate::replace( const T& t ) { + m_cache.replace( t ); return m_backEnd->replace( t ); } template void OPimAccessTemplate::invalidateCache() { - + m_cache.invalidate(); } template OPimAccessTemplate::BackEnd* OPimAccessTemplate::backEnd() { @@ -192,5 +232,16 @@ bool OPimAccessTemplate::wasChangedExternally()const { template void OPimAccessTemplate::setBackEnd( BackEnd* end ) { m_backEnd = end; + if (m_backEnd ) + m_backEnd->setFrontend( this ); +} +template +void OPimAccessTemplate::cache( const T& t ) const{ + /* hacky we need to work around the const*/ + ((OPimAccessTemplate*)this)->m_cache.add( t ); +} +template +void OPimAccessTemplate::setSaneCacheSize( int size ) { + m_cache.setSize( size ); } #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 @@ +#ifndef OPIE_PIM_CACHE_H +#define OPIE_PIM_CACHE_H + +#include + +#include "opimrecord.h" + +template +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 OPimCache { +public: + typedef OPimCacheItem 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 m_cache; +}; + +// Implementation +template +OPimCacheItem::OPimCacheItem( const T& t ) + : m_t(t) { +} +template +OPimCacheItem::~OPimCacheItem() { + +} +template +T OPimCacheItem::record()const { + return m_t; +} +template +void OPimCacheItem::setRecord( const T& t ) { + m_t = t; +} +// Cache +template +OPimCache::OPimCache() { + m_cache.setAutoDelete( TRUE ); +} +template +OPimCache::~OPimCache() { + +} +template +bool OPimCache::contains(int uid )const { + Item* it = m_cache.find( uid, FALSE ); + if (!it) + return false; + return true; +} +template +void OPimCache::invalidate() { + m_cache.clear(); +} +template +void OPimCache::setSize( int size ) { + m_cache.setMaxCost( size ); +} +template +T OPimCache::find(int uid )const { + Item *it = m_cache.find( uid ); + if (it) + return it->record(); + return T(); +} +template +void OPimCache::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 +void OPimCache::remove( int uid ) { + m_cache.remove( uid ); +} +template +void OPimCache::replace( const T& t) { + Item *it = m_cache.find( t.uid() ); + if ( it ) { + it->setRecord( t ); + } +} + +#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: 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::ORecordListIterator() { m_temp = 0l; m_end = true; m_record = T(); + /* forward */ + m_direction = TRUE; } template ORecordListIterator::~ORecordListIterator() { @@ -139,6 +142,7 @@ ORecordListIterator::ORecordListIterator( const ORecordListIterator& it) { m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; + m_direction = it.m_direction; } template @@ -156,11 +160,9 @@ template T ORecordListIterator::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::operator*() { template ORecordListIterator &ORecordListIterator::operator++() { + m_direction = true; if (m_current < m_uids.count() ) { m_end = false; ++m_current; @@ -179,6 +182,7 @@ ORecordListIterator &ORecordListIterator::operator++() { } template ORecordListIterator &ORecordListIterator::operator--() { + m_direction = false; if ( m_current > 0 ) { --m_current; m_end = false; @@ -207,7 +211,8 @@ bool ORecordListIterator::operator!=( const ORecordListIterator& it ) { template ORecordListIterator::ORecordListIterator( const QArray 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 @@ -254,6 +259,7 @@ return m_ids.count(); } template T ORecordList::operator[]( uint i ) { - return m_acc->find( m_ids[i] ); + /* forward */ + return m_acc->find( m_ids[i], m_ids, i ); } #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 @@ #ifndef OPIE_TEMPLATE_BASE_H #define OPIE_TEMPLATE_BASE_H +#include + #include "opimrecord.h" /** @@ -9,12 +11,21 @@ template 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& items, + uint current, CacheDirection dir = Forward )const = 0; + virtual void cache( const T& )const = 0; + virtual void setSaneCacheSize( int ) = 0; + }; -- cgit v0.9.0.2