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