/************************************************************** * * 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 _CONNECTIVITY_DBASE_INDEXNODE_HXX_ #define _CONNECTIVITY_DBASE_INDEXNODE_HXX_ #include "file/fcode.hxx" #include "file/FTable.hxx" #include "dbase/DIndexPage.hxx" #include "connectivity/FValue.hxx" #include #define NODE_NOTFOUND 0xFFFF #define PAGE_SIZE 512 namespace connectivity { namespace dbase { class ONDXNode; class ODbaseIndex; //================================================================== // Index Key //================================================================== typedef file::OOperand ONDXKey_BASE; class ONDXKey : public ONDXKey_BASE { friend class ONDXNode; sal_uInt32 nRecord; /* Satzzeiger */ ORowSetValue xValue; /* Schluesselwert */ public: ONDXKey(sal_uInt32 nRec=0); ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec); ONDXKey(const rtl::OUString& aStr, sal_uInt32 nRec = 0); ONDXKey(double aVal, sal_uInt32 nRec = 0); inline ONDXKey(const ONDXKey& rKey); inline ONDXKey& operator= (const ONDXKey& rKey); virtual void setValue(const ORowSetValue& _rVal); virtual const ORowSetValue& getValue() const; sal_uInt32 GetRecord() const { return nRecord; } void setRecord(sal_uInt32 _nRec) { nRecord = _nRec; } void ResetRecord() { nRecord = 0; } sal_Bool operator == (const ONDXKey& rKey) const; sal_Bool operator != (const ONDXKey& rKey) const; sal_Bool operator < (const ONDXKey& rKey) const; sal_Bool operator <= (const ONDXKey& rKey) const; sal_Bool operator > (const ONDXKey& rKey) const; sal_Bool operator >= (const ONDXKey& rKey) const; sal_Bool Load (SvFileStream& rStream, sal_Bool bText); sal_Bool Write(SvFileStream& rStream, sal_Bool bText); static sal_Bool IsText(sal_Int32 eType); private: StringCompare Compare(const ONDXKey& rKey) const; }; //================================================================== // Index Seitenverweis //================================================================== SV_DECL_REF(ONDXPage) // Basisklasse da weitere Informationen gehalten werden muessen class ONDXPagePtr : public ONDXPageRef { friend SvStream& operator << (SvStream &rStream, const ONDXPagePtr&); friend SvStream& operator >> (SvStream &rStream, ONDXPagePtr&); sal_uInt32 nPagePos; // Position in der Indexdatei public: ONDXPagePtr(sal_uInt32 nPos = 0):nPagePos(nPos){} ONDXPagePtr(const ONDXPagePtr& rRef); ONDXPagePtr(ONDXPage* pRefPage); ONDXPagePtr& operator=(const ONDXPagePtr& rRef); ONDXPagePtr& operator=(ONDXPage* pPageRef); sal_uInt32 GetPagePos() const {return nPagePos;} sal_Bool HasPage() const {return nPagePos != 0;} // sal_Bool Is() const { return isValid(); } }; //================================================================== // Index Seite //================================================================== class ONDXPage : public SvRefBase { friend class ODbaseIndex; friend SvStream& operator << (SvStream &rStream, const ONDXPage&); friend SvStream& operator >> (SvStream &rStream, ONDXPage&); sal_uInt32 nPagePos; // Position in der Indexdatei sal_Bool bModified : 1; sal_uInt16 nCount; ONDXPagePtr aParent, // VaterSeite aChild; // Zeiger auf rechte ChildPage ODbaseIndex& rIndex; ONDXNode* ppNodes; // array von Knoten public: // Knoten Operationen sal_uInt16 Count() const {return nCount;} sal_Bool Insert(ONDXNode& rNode, sal_uInt32 nRowsLeft = 0); sal_Bool Insert(sal_uInt16 nIndex, ONDXNode& rNode); sal_Bool Append(ONDXNode& rNode); sal_Bool Delete(sal_uInt16); void Remove(sal_uInt16); void Release(sal_Bool bSave = sal_True); void ReleaseFull(sal_Bool bSave = sal_True); // Aufteilen und Zerlegen ONDXNode Split(ONDXPage& rPage); void Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage); // Zugriffsoperationen ONDXNode& operator[] (sal_uInt16 nPos); const ONDXNode& operator[] (sal_uInt16 nPos) const; sal_Bool IsRoot() const; sal_Bool IsLeaf() const; sal_Bool IsModified() const; sal_Bool HasParent(); sal_Bool HasChild() const; sal_Bool IsFull() const; sal_uInt32 GetPagePos() const {return nPagePos;} ONDXPagePtr& GetChild(ODbaseIndex* pIndex = 0); // Parent braucht nicht nachgeladen zu werden ONDXPagePtr GetParent(); ODbaseIndex& GetIndex() {return rIndex;} const ODbaseIndex& GetIndex() const {return rIndex;} // Setzen des Childs, ueber Referenz, um die PagePos zu erhalten void SetChild(ONDXPagePtr aCh); void SetParent(ONDXPagePtr aPa); sal_uInt16 Search(const ONDXKey& rSearch); sal_uInt16 Search(const ONDXPage* pPage); void SearchAndReplace(const ONDXKey& rSearch, ONDXKey& rReplace); protected: ONDXPage(ODbaseIndex& rIndex, sal_uInt32 nPos, ONDXPage* = NULL); ~ONDXPage(); virtual void QueryDelete(); void SetModified(sal_Bool bMod) {bModified = bMod;} void SetPagePos(sal_uInt32 nPage) {nPagePos = nPage;} sal_Bool Find(const ONDXKey&); // rek. Abstieg sal_uInt16 FindPos(const ONDXKey& rKey) const; #if OSL_DEBUG_LEVEL > 1 void PrintPage(); #endif }; SV_IMPL_REF(ONDXPage); SvStream& operator << (SvStream &rStream, const ONDXPagePtr&); SvStream& operator >> (SvStream &rStream, ONDXPagePtr&); inline sal_Bool ONDXPage::IsRoot() const {return !aParent.Is();} inline sal_Bool ONDXPage::IsLeaf() const {return !aChild.HasPage();} inline sal_Bool ONDXPage::IsModified() const {return bModified;} inline sal_Bool ONDXPage::HasParent() {return aParent.Is();} inline sal_Bool ONDXPage::HasChild() const {return aChild.HasPage();} inline ONDXPagePtr ONDXPage::GetParent() {return aParent;} inline void ONDXPage::SetParent(ONDXPagePtr aPa = ONDXPagePtr()) { aParent = aPa; } inline void ONDXPage::SetChild(ONDXPagePtr aCh = ONDXPagePtr()) { aChild = aCh; if (aChild.Is()) aChild->SetParent(this); } SvStream& operator >> (SvStream &rStream, ONDXPage& rPage); SvStream& operator << (SvStream &rStream, const ONDXPage& rPage); typedef ::std::vector ONDXPageList; //================================================================== // Index Knoten //================================================================== class ONDXNode { friend class ONDXPage; ONDXPagePtr aChild; /* naechster Seitenverweis */ ONDXKey aKey; public: ONDXNode(){} ONDXNode(const ONDXKey& rKey, ONDXPagePtr aPagePtr = ONDXPagePtr()) :aChild(aPagePtr),aKey(rKey) {} // verweist der Knoten auf eine Seite sal_Bool HasChild() const {return aChild.HasPage();} // Ist ein Index angegeben, kann gegebenfalls die Seite nachgeladen werden ONDXPagePtr& GetChild(ODbaseIndex* pIndex = NULL, ONDXPage* = NULL); const ONDXKey& GetKey() const { return aKey;} ONDXKey& GetKey() { return aKey;} // Setzen des Childs, ueber Referenz, um die PagePos zu erhalten void SetChild(ONDXPagePtr aCh = ONDXPagePtr(), ONDXPage* = NULL); void SetKey(ONDXKey& rKey) {aKey = rKey;} void Write(SvStream &rStream, const ONDXPage& rPage) const; void Read(SvStream &rStream, ODbaseIndex&); }; //================================================================== // inline implementation //================================================================== // inline ONDXKey::ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec) // : ONDXKey_BASE(eType) // , nRecord(nRec),xValue(rVal) // { // } // inline ONDXKey::ONDXKey(const rtl::OUString& aStr, sal_uInt32 nRec) // : ONDXKey_BASE(::com::sun::star::sdbc::DataType::VARCHAR) // ,nRecord(nRec) // { // if (aStr.len()) // xValue = aStr; // } // inline ONDXKey::ONDXKey(double aVal, sal_uInt32 nRec) // : ONDXKey_BASE(::com::sun::star::sdbc::DataType::DOUBLE) // ,nRecord(nRec) // ,xValue(aVal) // { // } // inline ONDXKey::ONDXKey(sal_uInt32 nRec) // :nRecord(nRec) // { // } inline ONDXKey::ONDXKey(const ONDXKey& rKey) : ONDXKey_BASE(rKey.getDBType()) ,nRecord(rKey.nRecord) ,xValue(rKey.xValue) { } inline ONDXKey& ONDXKey::operator=(const ONDXKey& rKey) { if(&rKey == this) return *this; xValue = rKey.xValue; nRecord = rKey.nRecord; m_eDBType = rKey.getDBType(); return *this; } inline sal_Bool ONDXKey::operator == (const ONDXKey& rKey) const { if(&rKey == this) return sal_True; return Compare(rKey) == COMPARE_EQUAL; } inline sal_Bool ONDXKey::operator != (const ONDXKey& rKey) const { return !operator== (rKey); } inline sal_Bool ONDXKey::operator < (const ONDXKey& rKey) const { return Compare(rKey) == COMPARE_LESS; } inline sal_Bool ONDXKey::operator > (const ONDXKey& rKey) const { return Compare(rKey) == COMPARE_GREATER; } inline sal_Bool ONDXKey::operator <= (const ONDXKey& rKey) const { return !operator > (rKey); } inline sal_Bool ONDXKey::operator >= (const ONDXKey& rKey) const { return !operator< (rKey); } inline void ONDXNode::SetChild(ONDXPagePtr aCh, ONDXPage* pParent) { aChild = aCh; if (aChild.Is()) aChild->SetParent(pParent); } } } #endif // _CONNECTIVITY_DBASE_INDEXNODE_HXX_