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