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 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 109 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 116 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 & 123 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 & 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 & 139 Storage<ENTITY>::operator[](key_type i_id) const 140 { 141 return operator[](i_id.Value()); 142 } 143 144 template <class ENTITY> 145 inline ENTITY & 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 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 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 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 200 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 208 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 216 Storage<ENTITY>::End() const 217 { 218 return c_iter(aData.End()); 219 } 220 221 template <class ENTITY> 222 inline 223 typename Storage<ENTITY>::iter 224 Storage<ENTITY>::Begin() 225 { 226 return iter(aData.Begin()); 227 } 228 229 template <class ENTITY> 230 inline 231 typename Storage<ENTITY>::iter 232 Storage<ENTITY>::BeginUnreserved() 233 { 234 return iter(aData.BeginUnreserved()); 235 } 236 237 template <class ENTITY> 238 inline 239 typename Storage<ENTITY>::iter 240 Storage<ENTITY>::End() 241 { 242 return iter(aData.End()); 243 } 244 245 template <class ENTITY> 246 inline 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 * 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 * 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