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 
00038 class PQXX_LIBEXPORT CachedResult
00039 {
00040 public:
00041   typedef Result::size_type size_type;
00042   typedef size_type blocknum;
00043   typedef Result::Tuple Tuple;
00044 
00049   explicit CachedResult(pqxx::TransactionItf &,
00050                         const char Query[],
00051                         PGSTD::string BaseName="query",
00052                         size_type Granularity=100);
00053 
00054   // TODO: Iterators, begin(), end()
00055   // TODO: Metadata
00056   // TODO: Block replacement (limit cache size); then add capacity()
00057 
00058   const Tuple operator[](size_type i) const
00059   {
00060     return GetBlock(BlockFor(i))[Offset(i)];
00061   }
00062 
00063   const Tuple at(size_type i) const
00064   {
00065     return GetBlock(BlockFor(i)).at(Offset(i));
00066   }
00067 
00069 
00074   size_type size() const
00075   {
00076     if (m_Size == -1) DetermineSize();
00077     return m_Size;
00078   }
00079 
00080   
00082   bool empty() const
00083   {
00084     return (m_Size == 0) || (m_Cache.empty() && GetBlock(0).empty());
00085   }
00086 
00088   void clear();
00089 
00091   class const_iterator
00092   {
00093     const CachedResult &m_Home;
00094     CachedResult::size_type m_Row;
00095   public:
00096     explicit const_iterator(const CachedResult &Home) : m_Home(Home), m_Row(0){}
00097 
00098   private:
00099     // Not allowed:
00100     const_iterator();
00101   };
00102 
00103 private:
00104 
00105   class CacheEntry
00106   {
00107     int m_RefCount;
00108     Result m_Data;
00109 
00110   public:
00111     CacheEntry() : m_RefCount(0), m_Data() {}
00112     explicit CacheEntry(const Result &R) : m_RefCount(0), m_Data(R) {}
00113 
00114     const Result &Data() const { return m_Data; }
00115     int RefCount() const { return m_RefCount; }
00116   };
00117 
00118 
00119   blocknum BlockFor(size_type Row) const { return Row / m_Granularity; }
00120   size_type Offset(size_type Row) const { return Row % m_Granularity; }
00121 
00122   void MoveTo(blocknum) const;
00123 
00125   Result Fetch() const;
00126 
00127   Result GetBlock(blocknum b) const
00128   {
00129     CacheMap::const_iterator i = m_Cache.find(b);
00130     if (i != m_Cache.end()) return i->second.Data();
00131 
00132     MoveTo(b);
00133     return Fetch();
00134   }
00135 
00141   void DetermineSize() const;
00142 
00144   size_type m_Granularity;
00145 
00146   typedef PGSTD::map<blocknum, CacheEntry> CacheMap;
00147   mutable CacheMap m_Cache;
00148 
00149   mutable Cursor m_Cursor;
00150 
00152   mutable blocknum m_Pos;
00153 
00155   mutable size_type m_Size;
00156 
00162   mutable blocknum m_Lower, m_Upper;
00163 
00164   // Not allowed:
00165   CachedResult();
00166   CachedResult(const CachedResult &);
00167   CachedResult &operator=(const CachedResult &);
00168 };
00169 
00170 
00171 } // namespace pqxx
00172 
00173 #endif
00174 

Generated on Tue Dec 3 01:37:34 2002 for libpqxx by doxygen1.3-rc1