1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2012,
4 //  Sony Pictures Imageworks, Inc. and
5 //  Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
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
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // *       Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36 
37 #ifndef Alembic_AbcCoreHDF5_CacheImpl_h
38 #define Alembic_AbcCoreHDF5_CacheImpl_h
39 
40 #include <Alembic/AbcCoreHDF5/Foundation.h>
41 
42 namespace Alembic {
43 namespace AbcCoreHDF5 {
44 namespace ALEMBIC_VERSION_NS {
45 
46 //-*****************************************************************************
47 typedef Alembic::Util::weak_ptr<AbcA::ArraySample> ArraySampleWeakPtr;
48 
49 //-*****************************************************************************
50 class CacheImpl;
51 typedef Alembic::Util::shared_ptr<CacheImpl> CacheImplPtr;
52 typedef Alembic::Util::weak_ptr<CacheImpl> CacheImplWeakPtr;
53 
54 //-*****************************************************************************
55 //! This class is underimplemented. It ought to allow limits on storage.
56 //! Todo!
57 //! THIS CLASS IS NOT MULTITHREAD SAFE
58 class CacheImpl : public AbcA::ReadArraySampleCache
59 {
60 public:
61     //-*************************************************************************
62     // PUBLIC INTERFACE
63     //-*************************************************************************
64     CacheImpl();
65 
66     virtual ~CacheImpl();
67 
68     virtual AbcA::ReadArraySampleID
69     find( const AbcA::ArraySample::Key &iKey );
70 
71     virtual AbcA::ReadArraySampleID
72     store( const AbcA::ArraySample::Key &iKey,
73            AbcA::ArraySamplePtr iBytes );
74 
75 private:
76     //-*************************************************************************
77     // INTERNAL STORAGE
78     // Using the unordered map (hash map)
79     //-*************************************************************************
80     struct Record
81     {
RecordRecord82         Record(){}
RecordRecord83         Record( AbcA::ArraySamplePtr iGivenPtr,
84                 AbcA::ArraySamplePtr iDeleterPtr )
85           : given( iGivenPtr ),
86             weakDeleter( iDeleterPtr )
87         {
88             ABCA_ASSERT( iGivenPtr && iDeleterPtr,
89                          "Cannot record null records in CacheImpl" );
90             ABCA_ASSERT( iGivenPtr.get() == iDeleterPtr.get(),
91                          "Given Ptr must match contents of DeleterPtr" );
92         }
93 
94         // This is the original, given Array Sample Ptr.
95         AbcA::ArraySamplePtr given;
96 
97         // This is the one we've created which corresponds
98         // to this record. It has the same pointer as above,
99         // but has a special deleter that will instead tell this
100         // class to erase this record.
101         // This is how we facilitate cache management.
102         // Also: I LOVE SMART PTRS
103         // We don't store it directly because we want the destructor
104         // to get called whenever we're not using this in the world anymore.
105         ArraySampleWeakPtr weakDeleter;
106     };
107 
108 public:
109     class RecordDeleter;
110 
111 private:
112     friend class RecordDeleter;
113     AbcA::ArraySamplePtr lock( const AbcA::ArraySample::Key &iKey,
114                                AbcA::ArraySamplePtr iSamp );
115     void unlock( const AbcA::ArraySample::Key &iKey );
116 
117 public:
118     class RecordDeleter
119     {
120     private:
121         friend class CacheImpl;
RecordDeleter(const AbcA::ArraySample::Key & iKey,CacheImplPtr iCache)122         RecordDeleter( const AbcA::ArraySample::Key &iKey,
123                        CacheImplPtr iCache )
124           : m_key( iKey ),
125             m_cache( iCache ) {}
126 
127     public:
operator()128         void operator()( AbcA::ArraySample *iPtr )
129         {
130             CacheImplPtr cachePtr = m_cache.lock();
131             if ( cachePtr )
132             {
133                 cachePtr->unlock( m_key );
134             }
135         }
136 
137     private:
138         AbcA::ArraySample::Key m_key;
139         CacheImplWeakPtr m_cache;
140     };
141 
142 private:
143     typedef AbcA::UnorderedMapUtil<Record>::umap_type Map;
144     typedef AbcA::UnorderedMapUtil<AbcA::ArraySamplePtr>::umap_type
145     UnlockedMap;
146 
147     Map m_lockedMap;
148     UnlockedMap m_unlockedMap;
149 };
150 
151 //-*****************************************************************************
152 AbcA::ReadArraySampleCachePtr MakeCacheImplPtr();
153 
154 } // End namespace ALEMBIC_VERSION_NS
155 
156 using namespace ALEMBIC_VERSION_NS;
157 
158 } // End namespace AbcCoreHDF5
159 } // End namespace Alembic
160 
161 #endif
162