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