Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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  * See COPYING for copyright license.  If you did not receive a file called
00013  * COPYING with this source code, please notify the distributor of this mistake,
00014  * or contact the author.
00015  *
00016  *-------------------------------------------------------------------------
00017  */
00018 #ifndef PQXX_CACHEDRESULT_H
00019 #define PQXX_CACHEDRESULT_H
00020 
00021 #include <map>
00022 
00023 #include "pqxx/cursor.h"
00024 #include "pqxx/result.h"
00025 
00026 namespace pqxx
00027 {
00028 
00029 // TODO: Forward-only mode of operation?  Or write separate stream class?
00030 
00052 class PQXX_LIBEXPORT cachedresult
00053 {
00054 public:
00055   typedef result::size_type size_type;
00056   typedef size_type blocknum;
00057 
00059   typedef result::tuple tuple;
00060 
00062   typedef tuple Tuple;
00063 
00075   template<typename TRANSACTION> explicit
00076     cachedresult(TRANSACTION &T,
00077                  const char Query[],
00078                  const PGSTD::string &BaseName="query",
00079                  size_type Granularity=100) :                           //[t40]
00080       m_Granularity(Granularity),
00081       m_Cache(),
00082       m_Cursor(T, Query, BaseName, Granularity),
00083       m_EmptyResult(),
00084       m_HaveEmpty(false)
00085   {
00086     // Trigger build error if T has insufficient isolation level
00087     error_permitted_isolation_level(typename TRANSACTION::isolation_tag());
00088     init();
00089   }
00090 
00091 
00092   // TODO: Iterators, begin(), end()
00093   // TODO: Metadata
00094   // TODO: Block replacement (limit cache size); then add capacity()
00095 
00097 
00105   const tuple operator[](size_type i) const                             //[t41]
00106         { return GetBlock(BlockFor(i))[Offset(i)]; }
00107 
00109 
00120    const tuple at(size_type i) const                                    //[t40]
00121         { return GetBlock(BlockFor(i)).at(Offset(i)); }
00122 
00124   size_type size() const;                                               //[t40]
00125   
00127   bool empty() const;                                                   //[t47]
00128 
00129 private:
00130   typedef Cursor::pos pos;
00131 
00133 
00138   template<typename ISOLATIONTAG>
00139     static inline void error_permitted_isolation_level(ISOLATIONTAG) throw();
00140 
00141   void init();
00142 
00143   blocknum BlockFor(size_type Row) const throw () 
00144         { return Row / m_Granularity; }
00145   size_type Offset(size_type Row) const throw ()
00146         { return Row % m_Granularity; }
00147   Cursor::size_type FirstRowOf(blocknum Block) const throw ()
00148         { return Block*m_Granularity; }
00149 
00150   void MoveTo(blocknum) const;
00151 
00153   const result &Fetch() const;
00154 
00155   const result &GetBlock(blocknum b) const
00156   {
00157     CacheMap::const_iterator i = m_Cache.find(b);
00158     if (i != m_Cache.end()) return i->second;
00159 
00160     MoveTo(b);
00161     return Fetch();
00162   }
00163 
00165   size_type m_Granularity;
00166 
00167   typedef PGSTD::map<blocknum, const result> CacheMap;
00168   mutable CacheMap m_Cache;
00169 
00170   mutable Cursor m_Cursor;
00171   mutable result m_EmptyResult;
00172   mutable bool   m_HaveEmpty;
00173 
00174   // Not allowed:
00175   cachedresult();
00176   cachedresult(const cachedresult &);
00177   cachedresult &operator=(const cachedresult &);
00178 };
00179 
00181 typedef cachedresult CachedResult;
00182 
00183 template<> inline void
00184 cachedresult::error_permitted_isolation_level(isolation_traits<serializable>)
00185   throw () {}
00186 
00187 } // namespace pqxx
00188 
00189 #endif
00190 

Generated on Fri Oct 24 20:21:37 2003 for libpqxx by doxygen 1.3.4