1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef ARY_STORE_S_STORAGE_HXX
25 #define ARY_STORE_S_STORAGE_HXX
26 
27 // USED SERVICES
28 #include <ary/types.hxx>
29 #include "s_iterator.hxx"
30 
31 
32 
33 
34 namespace ary
35 {
36 namespace stg
37 {
38 
39 
40 /** The storage unit of one class of commomly stored repository
41     entities.
42 */
43 template <class ENTITY>
44 class Storage
45 {
46   public:
47     typedef Base<ENTITY>                        container_type;
48     typedef ary::TypedId<ENTITY>                key_type;
49     typedef stg::const_iterator<ENTITY>         c_iter;
50     typedef stg::iterator<ENTITY>               iter;
51 
52     // LIFECYCLE
~Storage()53     virtual             ~Storage() {}
54 
55     // OPERATORS
56     const ENTITY &      operator[](
57                             key_type            i_id ) const;
58     ENTITY &            operator[](
59                             key_type            i_id );
60     const ENTITY &      operator[](
61                             Rid                 i_index ) const;
62     ENTITY &            operator[](
63                             Rid                 i_index );
64     // OPERATIONS
65     /// Sets the id of the new entity.
66     key_type            Store_Entity(
67                             DYN ENTITY &        pass_newEntity );
68     /// Sets the id of the new entity.
69     void                Set_Reserved(
70                             uintt               i_index,
71                             DYN ENTITY &        pass_newEntity );
72     /// Sets the id of the new entity.
73     void                Replace_Entity(
74                             key_type            i_index,
75                             DYN ENTITY &        pass_newEntity );
76     // INQUIRY
77     bool                Exists(
78                             key_type            i_id ) const;
79     bool                Exists(
80                             Rid                 i_index ) const;
81 
82     c_iter              Begin() const;
83     c_iter              BeginUnreserved() const;
84     c_iter              End() const;
85 
86     // ACCESS
87     iter                Begin();
88     iter                BeginUnreserved();
89     iter                End();
90 
91   protected:
92                         Storage(
93                             uintt               i_nrOfReservedItems );
94   private:
95     // DATA
96     container_type      aData;
97 };
98 
99 
100 
101 
102 
103 
104 // IMPLEMENTATION
105 
106 // Used later, so implemented first.
107 template <class ENTITY>
108 inline bool
Exists(Rid i_index) const109 Storage<ENTITY>::Exists(Rid i_index) const
110 {
111     return 0 < i_index AND i_index < aData.Size();
112 }
113 
114 template <class ENTITY>
115 inline bool
Exists(key_type i_id) const116 Storage<ENTITY>::Exists(key_type i_id) const
117 {
118     return Exists(i_id.Value());
119 }
120 
121 template <class ENTITY>
122 inline const ENTITY &
operator [](Rid i_index) const123 Storage<ENTITY>::operator[](Rid i_index) const
124 {
125     csv_assert(Exists(i_index));
126     return * aData[i_index];
127 }
128 
129 template <class ENTITY>
130 inline ENTITY &
operator [](Rid i_index)131 Storage<ENTITY>::operator[](Rid i_index)
132 {
133     csv_assert(Exists(i_index));
134     return * aData[i_index];
135 }
136 
137 template <class ENTITY>
138 inline const ENTITY &
operator [](key_type i_id) const139 Storage<ENTITY>::operator[](key_type i_id) const
140 {
141     return operator[](i_id.Value());
142 }
143 
144 template <class ENTITY>
145 inline ENTITY &
operator [](key_type i_id)146 Storage<ENTITY>::operator[](key_type i_id)
147 {
148     return operator[](i_id.Value());
149 }
150 
151 template <class ENTITY>
152 typename Storage<ENTITY>::key_type
Store_Entity(DYN ENTITY & pass_newEntity)153 Storage<ENTITY>::Store_Entity(DYN ENTITY & pass_newEntity)
154 {
155     csv_assert( aData.Size() >= aData.ReservedSize() );
156     Rid
157         ret( aData.Add_Entity(pass_newEntity) );
158     pass_newEntity.Set_Id(ret);
159     return key_type(ret);
160 }
161 
162 template <class ENTITY>
163 void
Set_Reserved(uintt i_index,DYN ENTITY & pass_newEntity)164 Storage<ENTITY>::Set_Reserved(uintt           i_index,
165                               DYN ENTITY &    pass_newEntity)
166 {
167     // 0 must not be used.
168     csv_assert( i_index != 0 );
169     // Make sure, i_index actually is the id of a reserved item.
170     csv_assert( i_index < aData.ReservedSize() );
171 
172     // If there was a previous entity, it will be deleted by
173     // the destructor of pOldEntity.
174     Dyn<ENTITY>
175         pOldEntity(aData.Set_Entity(i_index, pass_newEntity));
176     pass_newEntity.Set_Id(i_index);
177 }
178 
179 template <class ENTITY>
180 void
Replace_Entity(key_type i_index,DYN ENTITY & pass_newEntity)181 Storage<ENTITY>::Replace_Entity( key_type       i_index,
182                                  DYN ENTITY &   pass_newEntity )
183 {
184     uintt
185         nIndex = i_index.Value();
186     // Make sure, i_index actually is the id of an existing,
187     // non reserved entity.
188     csv_assert( csv::in_range(aData.ReservedSize(), nIndex, aData.Size()) );
189 
190     // If there was a previous entity, it will be deleted by
191     // the destructor of pOldEntity.
192     Dyn<ENTITY>
193         pOldEntity(aData.Set_Entity(nIndex, pass_newEntity));
194     pass_newEntity.Set_Id(nIndex);
195 }
196 
197 template <class ENTITY>
198 inline
199 typename Storage<ENTITY>::c_iter
Begin() const200 Storage<ENTITY>::Begin() const
201 {
202     return c_iter(aData.Begin());
203 }
204 
205 template <class ENTITY>
206 inline
207 typename Storage<ENTITY>::c_iter
BeginUnreserved() const208 Storage<ENTITY>::BeginUnreserved() const
209 {
210     return c_iter(aData.BeginUnreserved());
211 }
212 
213 template <class ENTITY>
214 inline
215 typename Storage<ENTITY>::c_iter
End() const216 Storage<ENTITY>::End() const
217 {
218     return c_iter(aData.End());
219 }
220 
221 template <class ENTITY>
222 inline
223 typename Storage<ENTITY>::iter
Begin()224 Storage<ENTITY>::Begin()
225 {
226     return iter(aData.Begin());
227 }
228 
229 template <class ENTITY>
230 inline
231 typename Storage<ENTITY>::iter
BeginUnreserved()232 Storage<ENTITY>::BeginUnreserved()
233 {
234     return iter(aData.BeginUnreserved());
235 }
236 
237 template <class ENTITY>
238 inline
239 typename Storage<ENTITY>::iter
End()240 Storage<ENTITY>::End()
241 {
242     return iter(aData.End());
243 }
244 
245 template <class ENTITY>
246 inline
Storage(uintt i_nrOfReservedItems)247 Storage<ENTITY>::Storage(uintt i_nrOfReservedItems)
248     :   aData(i_nrOfReservedItems)
249 {
250     // Make sure Rid and uintt are the same type, because
251     // the interface of this uses Rid, but the interface of
252     // container_type uses uintt.
253     csv_assert( sizeof(uintt) == sizeof(Rid) );
254 }
255 
256 
257 
258 
259 // HELPER FUNCTIONS
260 
261 /** @return 0, if data are not there.
262 */
263 template <class ENTITY>
264 inline const ENTITY *
Search(const Storage<ENTITY> & i_storage,Rid i_id)265 Search( const Storage<ENTITY> &     i_storage,
266         Rid                         i_id )
267 {
268     if (NOT i_storage.Exists(i_id))
269         return 0;
270     return &i_storage[i_id];
271 }
272 
273 /** @return 0, if data are not there.
274 */
275 template <class ENTITY>
276 inline ENTITY *
SearchAccess(const Storage<ENTITY> & i_storage,Rid i_id)277 SearchAccess( const Storage<ENTITY> &   i_storage,
278               Rid                       i_id )
279 {
280     if (NOT i_storage.Exists(i_id))
281         return 0;
282     return &i_storage[i_id];
283 }
284 
285 
286 
287 
288 }   // namespace stg
289 }   // namespace ary
290 #endif
291