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/thread/mutex.hpp>
50 
51 #include "Field.h"
52 
53 //----------------------------------------------------------------------------//
54 
55 #include "ns.h"
56 
58 
59 //----------------------------------------------------------------------------//
60 // FieldCache
61 //----------------------------------------------------------------------------//
62 
63 /* \class FieldCache
64 
65  This class is used by Field3DInputFile::readField() to see if the
66  field being loaded already exists in memory. It uses the weak pointer
67  system in RefBase to check if a previously loaded field still resides
68  in memory. If it is, then readField() returns a pointer rather than
69  reading the data again from disk.
70 
71  \note FieldCache does not increment the reference count of cached fields,
72  so objects will be deallocated naturally.
73  */
74 
75 //----------------------------------------------------------------------------//
76 
77 template <typename Data_T>
79 {
80 public:
81 
82  // Typedefs ------------------------------------------------------------------
83 
85  typedef typename Field_T::Ptr FieldPtr;
86  typedef typename Field_T::WeakPtr WeakPtr;
87  typedef std::pair<WeakPtr, Field_T*> CacheEntry;
88  typedef std::map<std::string, CacheEntry> Cache;
89 
90  // Access to singleton -------------------------------------------------------
91 
93  static FieldCache& singleton();
94 
95  // Main methods --------------------------------------------------------------
96 
100  FieldPtr getCachedField(const std::string &filename,
101  const std::string &layerPath);
103  void cacheField(FieldPtr field, const std::string &filename,
104  const std::string &layerPath);
105 
106 private:
107 
108  // Utility functions --------------------------------------------------------
109 
111  std::string key(const std::string &filename,
112  const std::string &layerPath);
113 
114  // Data members -------------------------------------------------------------
115 
117  Cache m_cache;
121  static boost::mutex ms_creationMutex;
123  static boost::mutex ms_accessMutex;
124 };
125 
126 //----------------------------------------------------------------------------//
127 // FieldCache static member instantiation
128 //----------------------------------------------------------------------------//
129 
130 template <typename Data_T>
132 template <typename Data_T>
134 template <typename Data_T>
136 
137 //----------------------------------------------------------------------------//
138 // Implementations
139 //----------------------------------------------------------------------------//
140 
141 template <typename Data_T>
143 {
144  boost::mutex::scoped_lock lock(ms_creationMutex);
145  if (!ms_singleton) {
146  ms_singleton = new FieldCache;
147  }
148  return *ms_singleton;
149 }
150 
151 //----------------------------------------------------------------------------//
152 
153 template <typename Data_T>
155 FieldCache<Data_T>::getCachedField(const std::string &filename,
156  const std::string &layerPath)
157 {
158  boost::mutex::scoped_lock lock(ms_accessMutex);
159  // First see if the request has ever been processed
160  typename Cache::iterator i = m_cache.find(key(filename, layerPath));
161  if (i == m_cache.end()) {
162  return FieldPtr();
163  }
164  // Next, check if all weak_ptrs are valid
165  CacheEntry &entry = i->second;
166  WeakPtr weakPtr = entry.first;
167  if (weakPtr.expired()) {
168  return FieldPtr();
169  }
170  return FieldPtr(entry.second);
171 }
172 
173 //----------------------------------------------------------------------------//
174 
175 template <typename Data_T>
176 void FieldCache<Data_T>::cacheField(FieldPtr field, const std::string &filename,
177  const std::string &layerPath)
178 {
179  boost::mutex::scoped_lock lock(ms_accessMutex);
180  m_cache[key(filename, layerPath)] =
181  std::make_pair(field->weakPtr(), field.get());
182 }
183 
184 //----------------------------------------------------------------------------//
185 
186 template <typename Data_T>
187 std::string FieldCache<Data_T>::key(const std::string &filename,
188  const std::string &layerPath)
189 {
190  return filename + "/" + layerPath;
191 }
192 
193 //----------------------------------------------------------------------------//
194 
196 
197 //----------------------------------------------------------------------------//
198 
199 #endif
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
static boost::mutex ms_creationMutex
Mutex to prevent multiple allocaation of the singleton.
Definition: FieldCache.h:121
Field_T::WeakPtr WeakPtr
Definition: FieldCache.h:86
Field_T::Ptr FieldPtr
Definition: FieldCache.h:85
std::map< std::string, CacheEntry > Cache
Definition: FieldCache.h:88
Definition: Field.h:394
Field< Data_T > Field_T
Definition: FieldCache.h:84
FieldPtr getCachedField(const std::string &filename, const std::string &layerPath)
Checks the cache for a previously loaded field.
Definition: FieldCache.h:155
void cacheField(FieldPtr field, const std::string &filename, const std::string &layerPath)
Adds the given field to the cache.
Definition: FieldCache.h:176
static FieldCache * ms_singleton
The singleton instance.
Definition: FieldCache.h:119
static boost::mutex ms_accessMutex
Mutex to prevent reading from and writing to the cache concurrently.
Definition: FieldCache.h:123
boost::weak_ptr< RefBase > WeakPtr
Definition: RefCount.h:113
static FieldCache & singleton()
Returns a reference to the FieldCache singleton.
Definition: FieldCache.h:142
Contains Field, WritableField and ResizableField classes.
std::pair< WeakPtr, Field_T * > CacheEntry
Definition: FieldCache.h:87
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:187
Cache m_cache
The cache itself. Maps a &#39;key&#39; to a weak pointer and a raw pointer.
Definition: FieldCache.h:117
boost::intrusive_ptr< Field > Ptr
Definition: Field.h:400