| /************************************************************** |
| * |
| * 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 <ary/types.hxx> |
| #include "s_iterator.hxx" |
| |
| |
| |
| |
| namespace ary |
| { |
| namespace stg |
| { |
| |
| |
| /** The storage unit of one class of commomly stored repository |
| entities. |
| */ |
| template <class ENTITY> |
| class Storage |
| { |
| public: |
| typedef Base<ENTITY> container_type; |
| typedef ary::TypedId<ENTITY> key_type; |
| typedef stg::const_iterator<ENTITY> c_iter; |
| typedef stg::iterator<ENTITY> 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 <class ENTITY> |
| inline bool |
| Storage<ENTITY>::Exists(Rid i_index) const |
| { |
| return 0 < i_index AND i_index < aData.Size(); |
| } |
| |
| template <class ENTITY> |
| inline bool |
| Storage<ENTITY>::Exists(key_type i_id) const |
| { |
| return Exists(i_id.Value()); |
| } |
| |
| template <class ENTITY> |
| inline const ENTITY & |
| Storage<ENTITY>::operator[](Rid i_index) const |
| { |
| csv_assert(Exists(i_index)); |
| return * aData[i_index]; |
| } |
| |
| template <class ENTITY> |
| inline ENTITY & |
| Storage<ENTITY>::operator[](Rid i_index) |
| { |
| csv_assert(Exists(i_index)); |
| return * aData[i_index]; |
| } |
| |
| template <class ENTITY> |
| inline const ENTITY & |
| Storage<ENTITY>::operator[](key_type i_id) const |
| { |
| return operator[](i_id.Value()); |
| } |
| |
| template <class ENTITY> |
| inline ENTITY & |
| Storage<ENTITY>::operator[](key_type i_id) |
| { |
| return operator[](i_id.Value()); |
| } |
| |
| template <class ENTITY> |
| typename Storage<ENTITY>::key_type |
| Storage<ENTITY>::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 <class ENTITY> |
| void |
| Storage<ENTITY>::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<ENTITY> |
| pOldEntity(aData.Set_Entity(i_index, pass_newEntity)); |
| pass_newEntity.Set_Id(i_index); |
| } |
| |
| template <class ENTITY> |
| void |
| Storage<ENTITY>::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<ENTITY> |
| pOldEntity(aData.Set_Entity(nIndex, pass_newEntity)); |
| pass_newEntity.Set_Id(nIndex); |
| } |
| |
| template <class ENTITY> |
| inline |
| typename Storage<ENTITY>::c_iter |
| Storage<ENTITY>::Begin() const |
| { |
| return c_iter(aData.Begin()); |
| } |
| |
| template <class ENTITY> |
| inline |
| typename Storage<ENTITY>::c_iter |
| Storage<ENTITY>::BeginUnreserved() const |
| { |
| return c_iter(aData.BeginUnreserved()); |
| } |
| |
| template <class ENTITY> |
| inline |
| typename Storage<ENTITY>::c_iter |
| Storage<ENTITY>::End() const |
| { |
| return c_iter(aData.End()); |
| } |
| |
| template <class ENTITY> |
| inline |
| typename Storage<ENTITY>::iter |
| Storage<ENTITY>::Begin() |
| { |
| return iter(aData.Begin()); |
| } |
| |
| template <class ENTITY> |
| inline |
| typename Storage<ENTITY>::iter |
| Storage<ENTITY>::BeginUnreserved() |
| { |
| return iter(aData.BeginUnreserved()); |
| } |
| |
| template <class ENTITY> |
| inline |
| typename Storage<ENTITY>::iter |
| Storage<ENTITY>::End() |
| { |
| return iter(aData.End()); |
| } |
| |
| template <class ENTITY> |
| inline |
| Storage<ENTITY>::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 <class ENTITY> |
| inline const ENTITY * |
| Search( const Storage<ENTITY> & 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 <class ENTITY> |
| inline ENTITY * |
| SearchAccess( const Storage<ENTITY> & i_storage, |
| Rid i_id ) |
| { |
| if (NOT i_storage.Exists(i_id)) |
| return 0; |
| return &i_storage[i_id]; |
| } |
| |
| |
| |
| |
| } // namespace stg |
| } // namespace ary |
| #endif |