Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

cachedresult.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/cachedresult.h
00005  *
00006  *   DESCRIPTION
00007  *      definitions for the pqxx::CachedResult class and support classes.
00008  *   pqxx::CachedResult is a lazy-fetching, transparently-cached result set
00009  *
00010  * Copyright (c) 2001-2002, Jeroen T. Vermeulen <jtv@xs4all.nl>
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #ifndef PQXX_CACHEDRESULT_H
00015 #define PQXX_CACHEDRESULT_H
00016 
00017 #include <map>
00018 
00019 #include "pqxx/cursor.h"
00020 #include "pqxx/result.h"
00021 
00022 namespace pqxx
00023 {
00024 
00025 class TransactionItf;
00026 
00027 
00045 class PQXX_LIBEXPORT CachedResult
00046 {
00047 public:
00048   typedef Result::size_type size_type;
00049   typedef size_type blocknum;
00050   typedef Result::Tuple Tuple;
00051 
00056   explicit CachedResult(pqxx::TransactionItf &,
00057                         const char Query[],
00058                         PGSTD::string BaseName="query",
00059                         size_type Granularity=100);
00060 
00061   // TODO: Iterators, begin(), end()
00062   // TODO: Metadata
00063   // TODO: Block replacement (limit cache size); then add capacity()
00064 
00065   const Tuple operator[](size_type i) const
00066   {
00067     return GetBlock(BlockFor(i))[Offset(i)];
00068   }
00069 
00070   const Tuple at(size_type i) const
00071   {
00072     return GetBlock(BlockFor(i)).at(Offset(i));
00073   }
00074 
00076 
00081   size_type size() const
00082   {
00083     if (m_Size == -1) DetermineSize();
00084     return m_Size;
00085   }
00086 
00087   
00089   bool empty() const
00090   {
00091     return (m_Size == 0) || (m_Cache.empty() && GetBlock(0).empty());
00092   }
00093 
00095   void clear();
00096 
00098   class const_iterator
00099   {
00100     const CachedResult &m_Home;
00101     CachedResult::size_type m_Row;
00102   public:
00103     explicit const_iterator(const CachedResult &Home) : m_Home(Home), m_Row(0){}
00104 
00105   private:
00106     // Not allowed:
00107     const_iterator();
00108   };
00109 
00110 private:
00111 
00112   class CacheEntry
00113   {
00114     int m_RefCount;
00115     Result m_Data;
00116 
00117   public:
00118     CacheEntry() : m_RefCount(0), m_Data() {}
00119     explicit CacheEntry(const Result &R) : m_RefCount(0), m_Data(R) {}
00120 
00121     const Result &Data() const { return m_Data; }
00122     int RefCount() const { return m_RefCount; }
00123   };
00124 
00125 
00126   blocknum BlockFor(size_type Row) const { return Row / m_Granularity; }
00127   size_type Offset(size_type Row) const { return Row % m_Granularity; }
00128 
00129   void MoveTo(blocknum) const;
00130 
00132   Result Fetch() const;
00133 
00134   Result GetBlock(blocknum b) const
00135   {
00136     CacheMap::const_iterator i = m_Cache.find(b);
00137     if (i != m_Cache.end()) return i->second.Data();
00138 
00139     MoveTo(b);
00140     return Fetch();
00141   }
00142 
00148   void DetermineSize() const;
00149 
00151   size_type m_Granularity;
00152 
00153   typedef PGSTD::map<blocknum, CacheEntry> CacheMap;
00154   mutable CacheMap m_Cache;
00155 
00156   mutable Cursor m_Cursor;
00157 
00159   mutable blocknum m_Pos;
00160 
00162   mutable size_type m_Size;
00163 
00169   mutable blocknum m_Lower, m_Upper;
00170 
00171   // Not allowed:
00172   CachedResult();
00173   CachedResult(const CachedResult &);
00174   CachedResult &operator=(const CachedResult &);
00175 };
00176 
00177 
00178 } // namespace pqxx
00179 
00180 #endif
00181 

Generated on Mon Dec 9 01:51:45 2002 for libpqxx by doxygen1.3-rc1