Field3D
FieldCache.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2011 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
42 //----------------------------------------------------------------------------//
43 
44 #ifndef _INCLUDED_Field3D_FieldCache_H_
45 #define _INCLUDED_Field3D_FieldCache_H_
46 
47 //----------------------------------------------------------------------------//
48 
49 #include <boost/scoped_ptr.hpp>
50 #include <boost/thread/mutex.hpp>
51 #include <boost/foreach.hpp>
52 
53 #include "Field.h"
54 
55 //----------------------------------------------------------------------------//
56 
57 #include "ns.h"
58 
60 
61 //----------------------------------------------------------------------------//
62 // FieldCache
63 //----------------------------------------------------------------------------//
64 
65 /* \class FieldCache
66 
67  This class is used by Field3DInputFile::readField() to see if the
68  field being loaded already exists in memory. It uses the weak pointer
69  system in RefBase to check if a previously loaded field still resides
70  in memory. If it is, then readField() returns a pointer rather than
71  reading the data again from disk.
72 
73  \note FieldCache does not increment the reference count of cached fields,
74  so objects will be deallocated naturally.
75  */
76 
77 //----------------------------------------------------------------------------//
78 
79 template <typename Data_T>
81 {
82 public:
83 
84  // Typedefs ------------------------------------------------------------------
85 
87  typedef typename Field_T::Ptr FieldPtr;
88  typedef typename Field_T::WeakPtr WeakPtr;
89  typedef std::pair<WeakPtr, Field_T*> CacheEntry;
90  typedef std::map<std::string, CacheEntry> Cache;
91 
92  // Access to singleton -------------------------------------------------------
93 
95  static FieldCache& singleton();
96 
97  // Main methods --------------------------------------------------------------
98 
102  FieldPtr getCachedField(const std::string &filename,
103  const std::string &layerPath);
105  void cacheField(FieldPtr field, const std::string &filename,
106  const std::string &layerPath);
108  long long int memSize() const;
109 
110 private:
111 
112  // Utility functions --------------------------------------------------------
113 
115  std::string key(const std::string &filename,
116  const std::string &layerPath);
117 
118  // Data members -------------------------------------------------------------
119 
123  static boost::scoped_ptr<FieldCache> ms_singleton;
125  static boost::mutex ms_creationMutex;
127  static boost::mutex ms_accessMutex;
128 };
129 
130 //----------------------------------------------------------------------------//
131 // Implementations
132 //----------------------------------------------------------------------------//
133 
134 template <typename Data_T>
136 {
137  boost::mutex::scoped_lock lock(ms_creationMutex);
138  if (ms_singleton.get() == NULL) {
139  ms_singleton.reset(new FieldCache);
140  }
141  return *ms_singleton;
142 }
143 
144 //----------------------------------------------------------------------------//
145 
146 template <typename Data_T>
148 FieldCache<Data_T>::getCachedField(const std::string &filename,
149  const std::string &layerPath)
150 {
151  boost::mutex::scoped_lock lock(ms_accessMutex);
152  // First see if the request has ever been processed
153  typename Cache::iterator i = m_cache.find(key(filename, layerPath));
154  if (i == m_cache.end()) {
155  return FieldPtr();
156  }
157  // Next, check if all weak_ptrs are valid
158  CacheEntry &entry = i->second;
159  WeakPtr weakPtr = entry.first;
160  if (weakPtr.expired()) {
161  return FieldPtr();
162  }
163  return FieldPtr(entry.second);
164 }
165 
166 //----------------------------------------------------------------------------//
167 
168 template <typename Data_T>
169 void FieldCache<Data_T>::cacheField(FieldPtr field, const std::string &filename,
170  const std::string &layerPath)
171 {
172  boost::mutex::scoped_lock lock(ms_accessMutex);
173  m_cache[key(filename, layerPath)] =
174  std::make_pair(field->weakPtr(), field.get());
175 }
176 
177 //----------------------------------------------------------------------------//
178 
179 template <typename Data_T>
180 long long int FieldCache<Data_T>::memSize() const
181 {
182  boost::mutex::scoped_lock lock(ms_accessMutex);
183 
184  long long int memSize = 0;
185 
186  BOOST_FOREACH (const typename Cache::value_type &i, m_cache) {
187  // Check if pointer is valid
188  WeakPtr weakPtr = i.second.first;
189  if (weakPtr.expired()) {
190  continue;
191  } else {
192  // If valid, accumulate memory
193  memSize += i.second.second->memSize();
194  }
195  }
196 
197  return memSize;
198 }
199 
200 //----------------------------------------------------------------------------//
201 
202 template <typename Data_T>
203 std::string FieldCache<Data_T>::key(const std::string &filename,
204  const std::string &layerPath)
205 {
206  return filename + "/" + layerPath;
207 }
208 
209 //----------------------------------------------------------------------------//
210 
212 
213 //----------------------------------------------------------------------------//
214 
215 #endif
FIELD3D_NAMESPACE_HEADER_CLOSE
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
FieldCache::ms_accessMutex
static boost::mutex ms_accessMutex
Mutex to prevent reading from and writing to the cache concurrently.
Definition: FieldCache.h:127
Field::Ptr
boost::intrusive_ptr< Field > Ptr
Definition: Field.h:395
FieldCache::singleton
static FieldCache & singleton()
Returns a reference to the FieldCache singleton.
Definition: FieldCache.h:135
FieldCache::ms_singleton
static boost::scoped_ptr< FieldCache > ms_singleton
The singleton instance.
Definition: FieldCache.h:123
FieldCache::memSize
long long int memSize() const
Returns the memory use of all currently loaded fields.
Definition: FieldCache.h:180
FieldCache::key
std::string key(const std::string &filename, const std::string &layerPath)
Constructs the cache key for a given file and layer path.
Definition: FieldCache.h:203
FieldCache::CacheEntry
std::pair< WeakPtr, Field_T * > CacheEntry
Definition: FieldCache.h:89
FieldCache::m_cache
Cache m_cache
The cache itself. Maps a 'key' to a weak pointer and a raw pointer.
Definition: FieldCache.h:121
ns.h
FieldCache::WeakPtr
Field_T::WeakPtr WeakPtr
Definition: FieldCache.h:88
FieldCache::FieldPtr
Field_T::Ptr FieldPtr
Definition: FieldCache.h:87
Field.h
Contains Field, WritableField and ResizableField classes.
FieldCache::Field_T
Field< Data_T > Field_T
Definition: FieldCache.h:86
FieldCache::Cache
std::map< std::string, CacheEntry > Cache
Definition: FieldCache.h:90
FieldCache::getCachedField
FieldPtr getCachedField(const std::string &filename, const std::string &layerPath)
Checks the cache for a previously loaded field.
Definition: FieldCache.h:148
FieldCache::ms_creationMutex
static boost::mutex ms_creationMutex
Mutex to prevent multiple allocaation of the singleton.
Definition: FieldCache.h:125
FIELD3D_NAMESPACE_OPEN
Definition: FieldMapping.cpp:74
RefBase::WeakPtr
boost::weak_ptr< RefBase > WeakPtr
Definition: RefCount.h:113
FieldCache::cacheField
void cacheField(FieldPtr field, const std::string &filename, const std::string &layerPath)
Adds the given field to the cache.
Definition: FieldCache.h:169
Field
Definition: Field.h:390
FieldCache
Definition: FieldCache.h:81