/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #ifndef ARY_STORE_S_STORAGE_HXX #define ARY_STORE_S_STORAGE_HXX // USED SERVICES #include #include "s_iterator.hxx" namespace ary { namespace stg { /** The storage unit of one class of commomly stored repository entities. */ template class Storage { public: typedef Base container_type; typedef ary::TypedId key_type; typedef stg::const_iterator c_iter; typedef stg::iterator iter; // LIFECYCLE virtual ~Storage() {} // OPERATORS const ENTITY & operator[]( key_type i_id ) const; ENTITY & operator[]( key_type i_id ); const ENTITY & operator[]( Rid i_index ) const; ENTITY & operator[]( Rid i_index ); // OPERATIONS /// Sets the id of the new entity. key_type Store_Entity( DYN ENTITY & pass_newEntity ); /// Sets the id of the new entity. void Set_Reserved( uintt i_index, DYN ENTITY & pass_newEntity ); /// Sets the id of the new entity. void Replace_Entity( key_type i_index, DYN ENTITY & pass_newEntity ); // INQUIRY bool Exists( key_type i_id ) const; bool Exists( Rid i_index ) const; c_iter Begin() const; c_iter BeginUnreserved() const; c_iter End() const; // ACCESS iter Begin(); iter BeginUnreserved(); iter End(); protected: Storage( uintt i_nrOfReservedItems ); private: // DATA container_type aData; }; // IMPLEMENTATION // Used later, so implemented first. template inline bool Storage::Exists(Rid i_index) const { return 0 < i_index AND i_index < aData.Size(); } template inline bool Storage::Exists(key_type i_id) const { return Exists(i_id.Value()); } template inline const ENTITY & Storage::operator[](Rid i_index) const { csv_assert(Exists(i_index)); return * aData[i_index]; } template inline ENTITY & Storage::operator[](Rid i_index) { csv_assert(Exists(i_index)); return * aData[i_index]; } template inline const ENTITY & Storage::operator[](key_type i_id) const { return operator[](i_id.Value()); } template inline ENTITY & Storage::operator[](key_type i_id) { return operator[](i_id.Value()); } template typename Storage::key_type Storage::Store_Entity(DYN ENTITY & pass_newEntity) { csv_assert( aData.Size() >= aData.ReservedSize() ); Rid ret( aData.Add_Entity(pass_newEntity) ); pass_newEntity.Set_Id(ret); return key_type(ret); } template void Storage::Set_Reserved(uintt i_index, DYN ENTITY & pass_newEntity) { // 0 must not be used. csv_assert( i_index != 0 ); // Make sure, i_index actually is the id of a reserved item. csv_assert( i_index < aData.ReservedSize() ); // If there was a previous entity, it will be deleted by // the destructor of pOldEntity. Dyn pOldEntity(aData.Set_Entity(i_index, pass_newEntity)); pass_newEntity.Set_Id(i_index); } template void Storage::Replace_Entity( key_type i_index, DYN ENTITY & pass_newEntity ) { uintt nIndex = i_index.Value(); // Make sure, i_index actually is the id of an existing, // non reserved entity. csv_assert( csv::in_range(aData.ReservedSize(), nIndex, aData.Size()) ); // If there was a previous entity, it will be deleted by // the destructor of pOldEntity. Dyn pOldEntity(aData.Set_Entity(nIndex, pass_newEntity)); pass_newEntity.Set_Id(nIndex); } template inline typename Storage::c_iter Storage::Begin() const { return c_iter(aData.Begin()); } template inline typename Storage::c_iter Storage::BeginUnreserved() const { return c_iter(aData.BeginUnreserved()); } template inline typename Storage::c_iter Storage::End() const { return c_iter(aData.End()); } template inline typename Storage::iter Storage::Begin() { return iter(aData.Begin()); } template inline typename Storage::iter Storage::BeginUnreserved() { return iter(aData.BeginUnreserved()); } template inline typename Storage::iter Storage::End() { return iter(aData.End()); } template inline Storage::Storage(uintt i_nrOfReservedItems) : aData(i_nrOfReservedItems) { // Make sure Rid and uintt are the same type, because // the interface of this uses Rid, but the interface of // container_type uses uintt. csv_assert( sizeof(uintt) == sizeof(Rid) ); } // HELPER FUNCTIONS /** @return 0, if data are not there. */ template inline const ENTITY * Search( const Storage & i_storage, Rid i_id ) { if (NOT i_storage.Exists(i_id)) return 0; return &i_storage[i_id]; } /** @return 0, if data are not there. */ template inline ENTITY * SearchAccess( const Storage & i_storage, Rid i_id ) { if (NOT i_storage.Exists(i_id)) return 0; return &i_storage[i_id]; } } // namespace stg } // namespace ary #endif