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-2003, 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 // TODO: Forward-only mode of operation?  Or write separate stream class?
00028 
00046 class PQXX_LIBEXPORT CachedResult
00047 {
00048 public:
00049   typedef Result::size_type size_type;
00050   typedef size_type blocknum;
00051   typedef Result::Tuple Tuple;
00052 
00057   explicit CachedResult(pqxx::TransactionItf &,
00058                         const char Query[],
00059                         const PGSTD::string &BaseName="query",
00060                         size_type Granularity=100);
00061 
00062   // TODO: Iterators, begin(), end()
00063   // TODO: Metadata
00064   // TODO: Block replacement (limit cache size); then add capacity()
00065 
00066   const Tuple operator[](size_type i) const
00067   {
00068     return GetBlock(BlockFor(i))[Offset(i)];
00069   }
00070 
00071   const Tuple at(size_type i) const
00072   {
00073     return GetBlock(BlockFor(i)).at(Offset(i));
00074   }
00075 
00077   size_type size() const;
00078   
00080   bool empty() const;
00081 
00083   void clear();
00084 
00086   class const_iterator
00087   {
00088     const CachedResult &m_Home;
00089     CachedResult::size_type m_Row;
00090   public:
00091     explicit const_iterator(const CachedResult &Home) : m_Home(Home), m_Row(0){}
00092 
00093   private:
00094     // Not allowed:
00095     const_iterator();
00096   };
00097 
00098 private:
00099 
00100   typedef Cursor::pos pos;
00101 
00102   class CacheEntry
00103   {
00104     int m_RefCount;
00105     Result m_Data;
00106 
00107   public:
00108     CacheEntry() : m_RefCount(0), m_Data() {}
00109     explicit CacheEntry(const Result &R) : m_RefCount(0), m_Data(R) {}
00110 
00111     const Result &Data() const { return m_Data; }
00112     int RefCount() const { return m_RefCount; }
00113   };
00114 
00115 
00116   blocknum BlockFor(size_type Row) const throw () 
00117         { return Row / m_Granularity; }
00118   size_type Offset(size_type Row) const throw ()
00119         { return Row % m_Granularity; }
00120   Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00121         { return Block*m_Granularity; }
00122 
00123   void MoveTo(blocknum) const;
00124 
00126   Result Fetch() const;
00127 
00128   Result GetBlock(blocknum b) const
00129   {
00130     CacheMap::const_iterator i = m_Cache.find(b);
00131     if (i != m_Cache.end()) return i->second.Data();
00132 
00133     MoveTo(b);
00134     return Fetch();
00135   }
00136 
00138   size_type m_Granularity;
00139 
00140   typedef PGSTD::map<blocknum, CacheEntry> CacheMap;
00141   mutable CacheMap m_Cache;
00142 
00143   mutable Cursor m_Cursor;
00144 
00145   // Not allowed:
00146   CachedResult();
00147   CachedResult(const CachedResult &);
00148   CachedResult &operator=(const CachedResult &);
00149 };
00150 
00151 
00152 } // namespace pqxx
00153 
00154 #endif
00155 

Generated on Thu Jan 2 20:15:21 2003 for libpqxx by doxygen1.3-rc2