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 #include <Alembic/AbcCoreHDF5/CacheImpl.h>
38 
39 namespace Alembic {
40 namespace AbcCoreHDF5 {
41 namespace ALEMBIC_VERSION_NS {
42 
43 //-*****************************************************************************
CacheImpl()44 CacheImpl::CacheImpl()
45 {
46     // Nothing!
47 }
48 
49 //-*****************************************************************************
~CacheImpl()50 CacheImpl::~CacheImpl()
51 {
52     // Nothing!
53 }
54 
55 //-*****************************************************************************
56 AbcA::ReadArraySampleID
find(const AbcA::ArraySample::Key & iKey)57 CacheImpl::find( const AbcA::ArraySample::Key &iKey )
58 {
59     // Check the locked map! If we have already locked it, just return
60     // it locked!
61     Map::iterator foundIter = m_lockedMap.find( iKey );
62     if ( foundIter != m_lockedMap.end() )
63     {
64         AbcA::ArraySamplePtr deleterPtr =
65             (*foundIter).second.weakDeleter.lock();
66         assert( deleterPtr );
67 
68         return AbcA::ReadArraySampleID( iKey, deleterPtr );
69     }
70 
71     // If we get here, we're not in the locked map.
72     // Check the unlocked one.
73     UnlockedMap::iterator uFoundIter = m_unlockedMap.find( iKey );
74     if ( uFoundIter != m_unlockedMap.end() )
75     {
76         AbcA::ArraySamplePtr givenSampPtr = (*uFoundIter).second;
77         assert( givenSampPtr );
78 
79         AbcA::ArraySamplePtr deleterPtr = lock( iKey, givenSampPtr );
80         assert( deleterPtr );
81         assert( givenSampPtr.get() == deleterPtr.get() );
82 
83         // Remove it from the unlocked map.
84         m_unlockedMap.erase( uFoundIter );
85 
86         return AbcA::ReadArraySampleID( iKey, deleterPtr );
87     }
88 
89     // Didn't find it, return null sample ID
90     return AbcA::ReadArraySampleID();
91 }
92 
93 //-*****************************************************************************
94 AbcA::ReadArraySampleID
store(const AbcA::ArraySample::Key & iKey,AbcA::ArraySamplePtr iSamp)95 CacheImpl::store( const AbcA::ArraySample::Key &iKey,
96                   AbcA::ArraySamplePtr iSamp )
97 {
98     ABCA_ASSERT( iSamp, "Cannot store a null sample" );
99 
100     // Check to see if we already have it.
101     AbcA::ReadArraySampleID foundID = find( iKey );
102     if ( foundID )
103     {
104         return foundID;
105     }
106 
107     // Lock it.
108     AbcA::ArraySamplePtr deleterPtr = lock( iKey, iSamp );
109     assert( deleterPtr );
110 
111     return AbcA::ReadArraySampleID( iKey, deleterPtr );
112 }
113 
114 //-*****************************************************************************
115 AbcA::ArraySamplePtr
lock(const AbcA::ArraySample::Key & iKey,AbcA::ArraySamplePtr iGivenPtr)116 CacheImpl::lock( const AbcA::ArraySample::Key &iKey,
117                  AbcA::ArraySamplePtr iGivenPtr )
118 {
119     assert( iGivenPtr );
120 
121     // Lock it by creating a cache-managing deleter.
122     // This RecordDeleter simply tells this cache instance to nuke
123     // us.
124     RecordDeleter deleter( iKey,
125                            Alembic::Util::dynamic_pointer_cast<CacheImpl,
126                            AbcA::ReadArraySampleCache>( shared_from_this() ) );
127     AbcA::ArraySamplePtr deleterPtr( iGivenPtr.get(), deleter );
128 
129     // Add it to the locked map
130     Record record( iGivenPtr, deleterPtr );
131     m_lockedMap[iKey] = record;
132 
133     return deleterPtr;
134 }
135 
136 //-*****************************************************************************
unlock(const AbcA::ArraySample::Key & iKey)137 void CacheImpl::unlock( const AbcA::ArraySample::Key &iKey )
138 {
139     Map::iterator foundIter = m_lockedMap.find( iKey );
140     if ( foundIter != m_lockedMap.end() )
141     {
142         AbcA::ArraySamplePtr givenPtr = (*foundIter).second.given;
143         assert( givenPtr );
144         m_unlockedMap[iKey] = givenPtr;
145         m_lockedMap.erase( foundIter );
146     }
147 }
148 
149 //-*****************************************************************************
MakeCacheImplPtr()150 AbcA::ReadArraySampleCachePtr MakeCacheImplPtr()
151 {
152     return Alembic::Util::shared_ptr<CacheImpl>( new CacheImpl() );
153 }
154 
155 } // End namespace ALEMBIC_VERSION_NS
156 } // End namespace AbcCoreHDF5
157 } // End namespace Alembic
158