1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 30*cdf0e10cSrcweir #include "dbase/dindexnode.hxx" 31*cdf0e10cSrcweir #include "connectivity/CommonTools.hxx" 32*cdf0e10cSrcweir #include <osl/thread.h> 33*cdf0e10cSrcweir #include "dbase/DIndex.hxx" 34*cdf0e10cSrcweir #include <tools/debug.hxx> 35*cdf0e10cSrcweir #include "diagnose_ex.h" 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include <algorithm> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir using namespace connectivity; 41*cdf0e10cSrcweir using namespace connectivity::dbase; 42*cdf0e10cSrcweir using namespace connectivity::file; 43*cdf0e10cSrcweir using namespace com::sun::star::sdbc; 44*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 45*cdf0e10cSrcweir ONDXKey::ONDXKey(sal_uInt32 nRec) 46*cdf0e10cSrcweir :nRecord(nRec) 47*cdf0e10cSrcweir { 48*cdf0e10cSrcweir } 49*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 50*cdf0e10cSrcweir ONDXKey::ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec) 51*cdf0e10cSrcweir : ONDXKey_BASE(eType) 52*cdf0e10cSrcweir , nRecord(nRec) 53*cdf0e10cSrcweir , xValue(rVal) 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir } 56*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 57*cdf0e10cSrcweir ONDXKey::ONDXKey(const rtl::OUString& aStr, sal_uInt32 nRec) 58*cdf0e10cSrcweir : ONDXKey_BASE(::com::sun::star::sdbc::DataType::VARCHAR) 59*cdf0e10cSrcweir ,nRecord(nRec) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir if (aStr.getLength()) 62*cdf0e10cSrcweir { 63*cdf0e10cSrcweir xValue = aStr; 64*cdf0e10cSrcweir xValue.setBound(sal_True); 65*cdf0e10cSrcweir } 66*cdf0e10cSrcweir } 67*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir ONDXKey::ONDXKey(double aVal, sal_uInt32 nRec) 70*cdf0e10cSrcweir : ONDXKey_BASE(::com::sun::star::sdbc::DataType::DOUBLE) 71*cdf0e10cSrcweir ,nRecord(nRec) 72*cdf0e10cSrcweir ,xValue(aVal) 73*cdf0e10cSrcweir { 74*cdf0e10cSrcweir } 75*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir //================================================================== 78*cdf0e10cSrcweir // Index Seite 79*cdf0e10cSrcweir //================================================================== 80*cdf0e10cSrcweir ONDXPage::ONDXPage(ODbaseIndex& rInd, sal_uInt32 nPos, ONDXPage* pParent) 81*cdf0e10cSrcweir :nPagePos(nPos) 82*cdf0e10cSrcweir ,bModified(sal_False) 83*cdf0e10cSrcweir ,nCount(0) 84*cdf0e10cSrcweir ,aParent(pParent) 85*cdf0e10cSrcweir ,rIndex(rInd) 86*cdf0e10cSrcweir ,ppNodes(NULL) 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir sal_uInt16 nT = rIndex.getHeader().db_maxkeys; 89*cdf0e10cSrcweir ppNodes = new ONDXNode[nT]; 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir //------------------------------------------------------------------ 93*cdf0e10cSrcweir ONDXPage::~ONDXPage() 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir delete[] ppNodes; 96*cdf0e10cSrcweir // delete aParent; 97*cdf0e10cSrcweir // delete aChild; 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir //------------------------------------------------------------------ 100*cdf0e10cSrcweir void ONDXPage::QueryDelete() 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir // Ablegen im GarbageCollector 103*cdf0e10cSrcweir if (IsModified() && rIndex.m_pFileStream) 104*cdf0e10cSrcweir (*rIndex.m_pFileStream) << *this; 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir bModified = sal_False; 107*cdf0e10cSrcweir if (rIndex.UseCollector()) 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir if (aChild.Is()) 110*cdf0e10cSrcweir aChild->Release(sal_False); 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < rIndex.getHeader().db_maxkeys;i++) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir if (ppNodes[i].GetChild().Is()) 115*cdf0e10cSrcweir ppNodes[i].GetChild()->Release(sal_False); 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir ppNodes[i] = ONDXNode(); 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir RestoreNoDelete(); 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir nCount = 0; 122*cdf0e10cSrcweir aParent.Clear(); 123*cdf0e10cSrcweir rIndex.Collect(this); 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir else 126*cdf0e10cSrcweir SvRefBase::QueryDelete(); 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir //------------------------------------------------------------------ 129*cdf0e10cSrcweir ONDXPagePtr& ONDXPage::GetChild(ODbaseIndex* pIndex) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir if (!aChild.Is() && pIndex) 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir aChild = rIndex.CreatePage(aChild.GetPagePos(),this,aChild.HasPage()); 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir return aChild; 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir //------------------------------------------------------------------ 139*cdf0e10cSrcweir sal_uInt16 ONDXPage::FindPos(const ONDXKey& rKey) const 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir // sucht nach Platz fuer den vorgegeben key auf einer Seite 142*cdf0e10cSrcweir sal_uInt16 i = 0; 143*cdf0e10cSrcweir while (i < nCount && rKey > ((*this)[i]).GetKey()) 144*cdf0e10cSrcweir i++; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir return i; 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir //------------------------------------------------------------------ 150*cdf0e10cSrcweir sal_Bool ONDXPage::Find(const ONDXKey& rKey) 151*cdf0e10cSrcweir { 152*cdf0e10cSrcweir // sucht den vorgegeben key 153*cdf0e10cSrcweir // Besonderheit: gelangt der Algorithmus ans Ende 154*cdf0e10cSrcweir // wird immer die aktuelle Seite und die Knotenposition vermerkt 155*cdf0e10cSrcweir // auf die die Bedingung <= zutrifft 156*cdf0e10cSrcweir // dieses findet beim Insert besondere Beachtung 157*cdf0e10cSrcweir sal_uInt16 i = 0; 158*cdf0e10cSrcweir while (i < nCount && rKey > ((*this)[i]).GetKey()) 159*cdf0e10cSrcweir i++; 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir sal_Bool bResult = sal_False; 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir if (!IsLeaf()) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir // weiter absteigen 166*cdf0e10cSrcweir ONDXPagePtr aPage = (i==0) ? GetChild(&rIndex) : ((*this)[i-1]).GetChild(&rIndex, this); 167*cdf0e10cSrcweir bResult = aPage.Is() && aPage->Find(rKey); 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir else if (i == nCount) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir rIndex.m_aCurLeaf = this; 172*cdf0e10cSrcweir rIndex.m_nCurNode = i - 1; 173*cdf0e10cSrcweir bResult = sal_False; 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir else 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir bResult = rKey == ((*this)[i]).GetKey(); 178*cdf0e10cSrcweir rIndex.m_aCurLeaf = this; 179*cdf0e10cSrcweir rIndex.m_nCurNode = bResult ? i : i - 1; 180*cdf0e10cSrcweir } 181*cdf0e10cSrcweir return bResult; 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir //------------------------------------------------------------------ 185*cdf0e10cSrcweir sal_Bool ONDXPage::Insert(ONDXNode& rNode, sal_uInt32 nRowsLeft) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir // beim Erzeugen eines Index koennen auch mehrere Knoten eingefuegt werden 188*cdf0e10cSrcweir // diese sin dann aufsteigend sortiert 189*cdf0e10cSrcweir sal_Bool bAppend = nRowsLeft > 0; 190*cdf0e10cSrcweir if (IsFull()) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir sal_Bool bResult = sal_True; 193*cdf0e10cSrcweir ONDXNode aSplitNode; 194*cdf0e10cSrcweir if (bAppend) 195*cdf0e10cSrcweir aSplitNode = rNode; 196*cdf0e10cSrcweir else 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir // merken des letzten Knotens 199*cdf0e10cSrcweir aSplitNode = (*this)[nCount-1]; 200*cdf0e10cSrcweir if(rNode.GetKey() <= aSplitNode.GetKey()) 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir // und damit habe ich im folgenden praktisch eine Node weniger 204*cdf0e10cSrcweir if (IsLeaf() && this == &rIndex.m_aCurLeaf) 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir // geht davon aus, dass der Knoten, auf dem die Bedingung (<=) 207*cdf0e10cSrcweir // zutrifft, als m_nCurNode gesetzt ist 208*cdf0e10cSrcweir --nCount; // (sonst bekomme ich u.U. Assertions und GPFs - 60593) 209*cdf0e10cSrcweir bResult = Insert(rIndex.m_nCurNode + 1, rNode); 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir else // Position unbekannt 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir sal_uInt16 nPos = NODE_NOTFOUND; 214*cdf0e10cSrcweir while (++nPos < nCount && rNode.GetKey() > ((*this)[nPos]).GetKey()) ; 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir --nCount; // (sonst bekomme ich u.U. Assertions und GPFs - 60593) 217*cdf0e10cSrcweir bResult = Insert(nPos, rNode); 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir // konnte der neue Knoten eingefuegt werden 221*cdf0e10cSrcweir if (!bResult) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir nCount++; 224*cdf0e10cSrcweir aSplitNode = rNode; 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir } 227*cdf0e10cSrcweir else 228*cdf0e10cSrcweir aSplitNode = rNode; 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir sal_uInt32 nNewPagePos = rIndex.GetPageCount(); 232*cdf0e10cSrcweir sal_uInt32 nNewPageCount = nNewPagePos + 1; 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir // Herausgeloesten Knoten beim Vater einfuegen 235*cdf0e10cSrcweir if (!HasParent()) 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir // Kein Vater, dann neue Wurzel 238*cdf0e10cSrcweir ONDXPagePtr aNewRoot = rIndex.CreatePage(nNewPagePos + 1); 239*cdf0e10cSrcweir aNewRoot->SetChild(this); 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir rIndex.m_aRoot = aNewRoot; 242*cdf0e10cSrcweir rIndex.SetRootPos(nNewPagePos + 1); 243*cdf0e10cSrcweir rIndex.SetPageCount(++nNewPageCount); 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // neues blatt erzeugen und Seite aufteilen 247*cdf0e10cSrcweir ONDXPagePtr aNewPage = rIndex.CreatePage(nNewPagePos,aParent); 248*cdf0e10cSrcweir rIndex.SetPageCount(nNewPageCount); 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir // wieviele Knoten weren noch eingefuegt 251*cdf0e10cSrcweir // kommen noch ausreichend, dann koennen die Seiten bis zum Rand vollgestopft werden 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir ONDXNode aInnerNode; 254*cdf0e10cSrcweir if (!IsLeaf() || nRowsLeft < (sal_uInt32)(rIndex.GetMaxNodes() / 2)) 255*cdf0e10cSrcweir aInnerNode = Split(*aNewPage); 256*cdf0e10cSrcweir else 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir aInnerNode = (*this)[nCount - 1]; 259*cdf0e10cSrcweir //aInnerNode = aSplitNode; 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir // Knoten zeigt auf neue Seite 262*cdf0e10cSrcweir aInnerNode.SetChild(aNewPage); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir // innere Knoten haben keine Recordnummer 265*cdf0e10cSrcweir if (rIndex.isUnique()) 266*cdf0e10cSrcweir aInnerNode.GetKey().ResetRecord(); 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir // neue Seite zeigt nun auf Seite des herausgeloesten Knoten 269*cdf0e10cSrcweir if (!IsLeaf()) 270*cdf0e10cSrcweir aNewPage->SetChild(aInnerNode.GetChild()); 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir aNewPage->Append(aSplitNode); 274*cdf0e10cSrcweir ONDXPagePtr aTempParent = aParent; 275*cdf0e10cSrcweir if (IsLeaf()) 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir rIndex.m_aCurLeaf = aNewPage; 278*cdf0e10cSrcweir rIndex.m_nCurNode = rIndex.m_aCurLeaf->Count() - 1; 279*cdf0e10cSrcweir 280*cdf0e10cSrcweir // Freigeben nicht benoetigter Seiten, danach besteht keine Referenz 281*cdf0e10cSrcweir // mehr auf die Seite, danach kann 'this' nicht mehr gueltig sein!!! 282*cdf0e10cSrcweir ReleaseFull(); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir // Einfuegen des herausgeloesten Knotens 286*cdf0e10cSrcweir return aTempParent->Insert(aInnerNode); 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir else // Seite einfach weiter auffuellen 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir if (bAppend) 291*cdf0e10cSrcweir { 292*cdf0e10cSrcweir if (IsLeaf()) 293*cdf0e10cSrcweir rIndex.m_nCurNode = nCount - 1; 294*cdf0e10cSrcweir return Append(rNode); 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir else 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir sal_uInt16 nNodePos = FindPos(rNode.GetKey()); 299*cdf0e10cSrcweir if (IsLeaf()) 300*cdf0e10cSrcweir rIndex.m_nCurNode = nNodePos; 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir return Insert(nNodePos, rNode); 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir //------------------------------------------------------------------ 308*cdf0e10cSrcweir sal_Bool ONDXPage::Insert(sal_uInt16 nPos, ONDXNode& rNode) 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir sal_uInt16 nMaxCount = rIndex.getHeader().db_maxkeys; 311*cdf0e10cSrcweir if (nPos >= nMaxCount) 312*cdf0e10cSrcweir return sal_False; 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir if (nCount) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir ++nCount; 317*cdf0e10cSrcweir // nach rechts verschieben 318*cdf0e10cSrcweir for (sal_uInt16 i = std::min((sal_uInt16)(nMaxCount-1), (sal_uInt16)(nCount-1)); nPos < i; --i) 319*cdf0e10cSrcweir (*this)[i] = (*this)[i-1]; 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir else 322*cdf0e10cSrcweir if (nCount < nMaxCount) 323*cdf0e10cSrcweir nCount++; 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir // einfuegen an der Position 326*cdf0e10cSrcweir ONDXNode& rInsertNode = (*this)[nPos]; 327*cdf0e10cSrcweir rInsertNode = rNode; 328*cdf0e10cSrcweir if (rInsertNode.GetChild().Is()) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir rInsertNode.GetChild()->SetParent(this); 331*cdf0e10cSrcweir rNode.GetChild()->SetParent(this); 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir bModified = sal_True; 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir return sal_True; 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir //------------------------------------------------------------------ 340*cdf0e10cSrcweir sal_Bool ONDXPage::Append(ONDXNode& rNode) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir DBG_ASSERT(!IsFull(), "kein Append moeglich"); 343*cdf0e10cSrcweir return Insert(nCount, rNode); 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir //------------------------------------------------------------------ 346*cdf0e10cSrcweir void ONDXPage::Release(sal_Bool bSave) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir // freigeben der Pages 349*cdf0e10cSrcweir if (aChild.Is()) 350*cdf0e10cSrcweir aChild->Release(bSave); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir // Pointer freigeben 353*cdf0e10cSrcweir aChild.Clear(); 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < rIndex.getHeader().db_maxkeys;i++) 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir if (ppNodes[i].GetChild()) 358*cdf0e10cSrcweir ppNodes[i].GetChild()->Release(bSave); 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir ppNodes[i].GetChild().Clear(); 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir aParent = NULL; 363*cdf0e10cSrcweir } 364*cdf0e10cSrcweir //------------------------------------------------------------------ 365*cdf0e10cSrcweir void ONDXPage::ReleaseFull(sal_Bool bSave) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir ONDXPagePtr aTempParent = aParent; 368*cdf0e10cSrcweir Release(bSave); 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir if (aTempParent.Is()) 371*cdf0e10cSrcweir { 372*cdf0e10cSrcweir // Freigeben nicht benoetigter Seiten, danach besteht keine Referenz 373*cdf0e10cSrcweir // mehr auf die Seite, danach kann 'this' nicht mehr gueltig sein!!! 374*cdf0e10cSrcweir sal_uInt16 nParentPos = aTempParent->Search(this); 375*cdf0e10cSrcweir if (nParentPos != NODE_NOTFOUND) 376*cdf0e10cSrcweir (*aTempParent)[nParentPos].GetChild().Clear(); 377*cdf0e10cSrcweir else 378*cdf0e10cSrcweir aTempParent->GetChild().Clear(); 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir //------------------------------------------------------------------ 382*cdf0e10cSrcweir sal_Bool ONDXPage::Delete(sal_uInt16 nNodePos) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir if (IsLeaf()) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir // Letztes Element wird geloescht 387*cdf0e10cSrcweir if (nNodePos == (nCount - 1)) 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir ONDXNode aNode = (*this)[nNodePos]; 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir // beim Parent muss nun der KeyValue ausgetauscht werden 392*cdf0e10cSrcweir if (HasParent()) 393*cdf0e10cSrcweir aParent->SearchAndReplace(aNode.GetKey(), 394*cdf0e10cSrcweir (*this)[nNodePos-1].GetKey()); 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir // Loeschen des Knoten 399*cdf0e10cSrcweir Remove(nNodePos); 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir // Unterlauf 402*cdf0e10cSrcweir if (HasParent() && nCount < (rIndex.GetMaxNodes() / 2)) 403*cdf0e10cSrcweir { 404*cdf0e10cSrcweir // Feststellen, welcher Knoten auf die Seite zeigt 405*cdf0e10cSrcweir sal_uInt16 nParentNodePos = aParent->Search(this); 406*cdf0e10cSrcweir // letzte Element auf Vaterseite 407*cdf0e10cSrcweir // -> zusammenlegen mit vorletzter Seite 408*cdf0e10cSrcweir if (nParentNodePos == (aParent->Count() - 1)) 409*cdf0e10cSrcweir { 410*cdf0e10cSrcweir if (!nParentNodePos) 411*cdf0e10cSrcweir // zusammenlegen mit linken nachbarn 412*cdf0e10cSrcweir Merge(nParentNodePos,aParent->GetChild(&rIndex)); 413*cdf0e10cSrcweir else 414*cdf0e10cSrcweir Merge(nParentNodePos,(*aParent)[nParentNodePos-1].GetChild(&rIndex,aParent)); 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir // sonst Seite mit naechster Seite zusammenlegen 417*cdf0e10cSrcweir else 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir // zusammenlegen mit rechten nachbarn 420*cdf0e10cSrcweir Merge(nParentNodePos + 1,((*aParent)[nParentNodePos + 1].GetChild(&rIndex,aParent))); 421*cdf0e10cSrcweir nParentNodePos++; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir if (HasParent() && !(*aParent)[nParentNodePos].HasChild()) 424*cdf0e10cSrcweir aParent->Delete(nParentNodePos); 425*cdf0e10cSrcweir /* 426*cdf0e10cSrcweir // letzte Element auf Vaterseite 427*cdf0e10cSrcweir // -> zusammenlegen mit vorletzter Seite 428*cdf0e10cSrcweir if (nParentNodePos == (aParent->Count() - 1)) 429*cdf0e10cSrcweir { 430*cdf0e10cSrcweir if (!nParentNodePos) 431*cdf0e10cSrcweir // zusammenlegen mit linken nachbarn 432*cdf0e10cSrcweir Merge(nParentNodePos,aParent->GetChild(&rIndex)); 433*cdf0e10cSrcweir else 434*cdf0e10cSrcweir Merge(nParentNodePos,(*aParent)[nParentNodePos-1].GetChild(&rIndex,aParent)); 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir // sonst Seite mit naechster Seite zusammenlegen 437*cdf0e10cSrcweir else if(nParentNodePos != NODE_NOTFOUND) 438*cdf0e10cSrcweir { 439*cdf0e10cSrcweir // zusammenlegen mit rechten nachbarn 440*cdf0e10cSrcweir Merge(nParentNodePos + 1,((*aParent)[nParentNodePos + 1].GetChild(&rIndex,aParent))); 441*cdf0e10cSrcweir nParentNodePos++; 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir else // Sonderbehandlung 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir // Page ist aChild Page vom Parent => erste Page aus ppNodes an aChild anhaengen 446*cdf0e10cSrcweir Merge(0,(*aParent)[0].GetChild(&rIndex,aParent)); 447*cdf0e10cSrcweir nParentNodePos = 0; 448*cdf0e10cSrcweir } 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir if (HasParent() && !(*aParent)[nParentNodePos].HasChild()) 451*cdf0e10cSrcweir aParent->Delete(nParentNodePos); 452*cdf0e10cSrcweir */ 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir else if (IsRoot()) 456*cdf0e10cSrcweir // Sicherstellen das die Position der Wurzel festgehalten wird 457*cdf0e10cSrcweir rIndex.SetRootPos(nPagePos); 458*cdf0e10cSrcweir return sal_True; 459*cdf0e10cSrcweir } 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir //------------------------------------------------------------------ 463*cdf0e10cSrcweir ONDXNode ONDXPage::Split(ONDXPage& rPage) 464*cdf0e10cSrcweir { 465*cdf0e10cSrcweir DBG_ASSERT(IsFull(), "Falsches Splitting"); 466*cdf0e10cSrcweir /* Aufteilen einer Seite auf zwei 467*cdf0e10cSrcweir Blatt: 468*cdf0e10cSrcweir Seite 1 behaelt (n - (n/2)) 469*cdf0e10cSrcweir Seite 2 erhaelt (n/2) 470*cdf0e10cSrcweir Knoten n/2 wird dupliziert 471*cdf0e10cSrcweir Innerer Knoten: 472*cdf0e10cSrcweir Seite 1 behaelt (n+1)/2 473*cdf0e10cSrcweir Seite 2 erhaelt (n/2-1) 474*cdf0e10cSrcweir Knoten ((n+1)/2 + 1) : wird herausgenommen 475*cdf0e10cSrcweir */ 476*cdf0e10cSrcweir ONDXNode aResultNode; 477*cdf0e10cSrcweir if (IsLeaf()) 478*cdf0e10cSrcweir { 479*cdf0e10cSrcweir for (sal_uInt16 i = (nCount - (nCount / 2)), j = 0 ; i < nCount; i++) 480*cdf0e10cSrcweir rPage.Insert(j++,(*this)[i]); 481*cdf0e10cSrcweir 482*cdf0e10cSrcweir // dieser Knoten enthaelt einen Schluessel der noch einmal im Tree vorkommt 483*cdf0e10cSrcweir // und ersetzt werden muss 484*cdf0e10cSrcweir ONDXNode aLastNode = (*this)[nCount - 1]; 485*cdf0e10cSrcweir nCount = nCount - (nCount / 2); 486*cdf0e10cSrcweir aResultNode = (*this)[nCount - 1]; 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir if (HasParent()) 489*cdf0e10cSrcweir aParent->SearchAndReplace(aLastNode.GetKey(), 490*cdf0e10cSrcweir aResultNode.GetKey()); 491*cdf0e10cSrcweir } 492*cdf0e10cSrcweir else 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir for (sal_uInt16 i = (nCount + 1) / 2 + 1, j = 0 ; i < nCount; i++) 495*cdf0e10cSrcweir rPage.Insert(j++,(*this)[i]); 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir aResultNode = (*this)[(nCount + 1) / 2]; 498*cdf0e10cSrcweir nCount = (nCount + 1) / 2; 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir // neue Seite zeigt nun auf Seite des herausgeloesten Knoten 501*cdf0e10cSrcweir rPage.SetChild(aResultNode.GetChild()); 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir // Knoten zeigt auf neue Seite 504*cdf0e10cSrcweir aResultNode.SetChild(&rPage); 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir // innere Knoten haben keine Recordnummer 507*cdf0e10cSrcweir if (rIndex.isUnique()) 508*cdf0e10cSrcweir aResultNode.GetKey().ResetRecord(); 509*cdf0e10cSrcweir bModified = sal_True; 510*cdf0e10cSrcweir return aResultNode; 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir //------------------------------------------------------------------ 514*cdf0e10cSrcweir void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage) 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir DBG_ASSERT(HasParent(), "kein Vater vorhanden"); 517*cdf0e10cSrcweir DBG_ASSERT(nParentNodePos != NODE_NOTFOUND, "Falscher Indexaufbau"); 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir /* Zusammenlegen zweier Seiten */ 520*cdf0e10cSrcweir ONDXNode aResultNode; 521*cdf0e10cSrcweir sal_uInt16 nMaxNodes = rIndex.GetMaxNodes(), 522*cdf0e10cSrcweir nMaxNodes_2 = nMaxNodes / 2; 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir // Feststellen ob Seite rechter oder linker Nachbar 525*cdf0e10cSrcweir sal_Bool bRight = ((*xPage)[0].GetKey() > (*this)[0].GetKey()); // sal_True, wenn xPage die rechte Seite ist 526*cdf0e10cSrcweir sal_uInt16 nNewCount = (*xPage).Count() + Count(); 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir if (IsLeaf()) 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir // Bedingung fuers zusammenlegen 531*cdf0e10cSrcweir if (nNewCount < (nMaxNodes_2 * 2)) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir sal_uInt16 nLastNode = bRight ? Count() - 1 : xPage->Count() - 1; 534*cdf0e10cSrcweir if (bRight) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife"); 537*cdf0e10cSrcweir // alle Knoten aus xPage auf den linken Knoten verschieben (anhaengen) 538*cdf0e10cSrcweir while (xPage->Count()) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir Append((*xPage)[0]); 541*cdf0e10cSrcweir xPage->Remove(0); 542*cdf0e10cSrcweir } 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir else 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife"); 547*cdf0e10cSrcweir // xPage ist die linke Page und THIS die rechte 548*cdf0e10cSrcweir while (xPage->Count()) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir Insert(0,(*xPage)[xPage->Count()-1]); 551*cdf0e10cSrcweir xPage->Remove(xPage->Count()-1); 552*cdf0e10cSrcweir } 553*cdf0e10cSrcweir // alte Position von xPage beim Parent mit this ersetzen 554*cdf0e10cSrcweir if (nParentNodePos) 555*cdf0e10cSrcweir (*aParent)[nParentNodePos-1].SetChild(this,aParent); 556*cdf0e10cSrcweir else // oder als rechten Knoten setzen 557*cdf0e10cSrcweir aParent->SetChild(this); 558*cdf0e10cSrcweir aParent->SetModified(sal_True); 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir // Child beziehung beim Vaterknoten aufheben 563*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(); 564*cdf0e10cSrcweir // Austauschen des KnotenWertes, nur wenn geaenderte Page 565*cdf0e10cSrcweir // die linke ist, ansonsten werde 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir if(aParent->IsRoot() && aParent->Count() == 1) 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir (*aParent)[0].SetChild(); 570*cdf0e10cSrcweir aParent->ReleaseFull(); 571*cdf0e10cSrcweir aParent = NULL; 572*cdf0e10cSrcweir rIndex.SetRootPos(nPagePos); 573*cdf0e10cSrcweir rIndex.m_aRoot = this; 574*cdf0e10cSrcweir SetModified(sal_True); 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir else 577*cdf0e10cSrcweir aParent->SearchAndReplace((*this)[nLastNode].GetKey(),(*this)[nCount-1].GetKey()); 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir xPage->SetModified(sal_False); 580*cdf0e10cSrcweir xPage->ReleaseFull(); // wird nicht mehr benoetigt 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir // Ausgleichen der Elemente nNewCount >= (nMaxNodes_2 * 2) 583*cdf0e10cSrcweir else 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir if (bRight) 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir // alle Knoten aus xPage auf den linken Knoten verschieben (anhaengen) 588*cdf0e10cSrcweir ONDXNode aReplaceNode = (*this)[nCount - 1]; 589*cdf0e10cSrcweir while (nCount < nMaxNodes_2) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir Append((*xPage)[0]); 592*cdf0e10cSrcweir xPage->Remove(0); 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir // Austauschen des KnotenWertes: Setzt alten letzten Wert durch den letzten von xPage 595*cdf0e10cSrcweir aParent->SearchAndReplace(aReplaceNode.GetKey(),(*this)[nCount-1].GetKey()); 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir else 598*cdf0e10cSrcweir { 599*cdf0e10cSrcweir // alle Knoten aus this vor die xPage Knoten einfuegen 600*cdf0e10cSrcweir ONDXNode aReplaceNode = (*this)[nCount - 1]; 601*cdf0e10cSrcweir while (xPage->Count() < nMaxNodes_2) 602*cdf0e10cSrcweir { 603*cdf0e10cSrcweir xPage->Insert(0,(*this)[nCount-1]); 604*cdf0e10cSrcweir Remove(nCount-1); 605*cdf0e10cSrcweir } 606*cdf0e10cSrcweir // Austauschen des KnotenWertes 607*cdf0e10cSrcweir aParent->SearchAndReplace(aReplaceNode.GetKey(),(*this)[Count()-1].GetKey()); 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir else // !IsLeaf() 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir // Bedingung fuers zusammenlegen 614*cdf0e10cSrcweir if (nNewCount < nMaxNodes_2 * 2) 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir if (bRight) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife"); 619*cdf0e10cSrcweir // Vaterknoten wird mit integriert 620*cdf0e10cSrcweir // erhaelt zunaechst Child von xPage 621*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(xPage->GetChild(),aParent); 622*cdf0e10cSrcweir Append((*aParent)[nParentNodePos]); 623*cdf0e10cSrcweir for (sal_uInt16 i = 0 ; i < xPage->Count(); i++) 624*cdf0e10cSrcweir Append((*xPage)[i]); 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir else 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife"); 629*cdf0e10cSrcweir // Vaterknoten wird mit integriert 630*cdf0e10cSrcweir // erhaelt zunaechst Child 631*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(GetChild(),aParent); // Parent merkt sich mein Child 632*cdf0e10cSrcweir Insert(0,(*aParent)[nParentNodePos]); // Node vom Parent bei mir einfuegen 633*cdf0e10cSrcweir while (xPage->Count()) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir Insert(0,(*xPage)[xPage->Count()-1]); 636*cdf0e10cSrcweir xPage->Remove(xPage->Count()-1); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir SetChild(xPage->GetChild()); 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir if (nParentNodePos) 641*cdf0e10cSrcweir (*aParent)[nParentNodePos-1].SetChild(this,aParent); 642*cdf0e10cSrcweir else 643*cdf0e10cSrcweir aParent->SetChild(this); 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir // danach wird der Vaterknoten zurueckgesetzt 647*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(); 648*cdf0e10cSrcweir aParent->SetModified(sal_True); 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir if(aParent->IsRoot() && aParent->Count() == 1) 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir (*aParent).SetChild(); 653*cdf0e10cSrcweir aParent->ReleaseFull(); 654*cdf0e10cSrcweir aParent = NULL; 655*cdf0e10cSrcweir rIndex.SetRootPos(nPagePos); 656*cdf0e10cSrcweir rIndex.m_aRoot = this; 657*cdf0e10cSrcweir SetModified(sal_True); 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir else if(nParentNodePos) 660*cdf0e10cSrcweir // Austauschen des KnotenWertes 661*cdf0e10cSrcweir // beim Append wird der Bereich erweitert, beim INsert verweist der alte Knoten von xPage auf this 662*cdf0e10cSrcweir // deshalb muss der Knoten auch hier aktualisiert werden 663*cdf0e10cSrcweir aParent->SearchAndReplace((*aParent)[nParentNodePos-1].GetKey(),(*aParent)[nParentNodePos].GetKey()); 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir xPage->SetModified(sal_False); 666*cdf0e10cSrcweir xPage->ReleaseFull(); 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir // Ausgleichen der Elemente 669*cdf0e10cSrcweir else 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir if (bRight) 672*cdf0e10cSrcweir { 673*cdf0e10cSrcweir while (nCount < nMaxNodes_2) 674*cdf0e10cSrcweir { 675*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(xPage->GetChild(),aParent); 676*cdf0e10cSrcweir Append((*aParent)[nParentNodePos]); 677*cdf0e10cSrcweir (*aParent)[nParentNodePos] = (*xPage)[0]; 678*cdf0e10cSrcweir xPage->Remove(0); 679*cdf0e10cSrcweir } 680*cdf0e10cSrcweir xPage->SetChild((*aParent)[nParentNodePos].GetChild()); 681*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(xPage,aParent); 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir else 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir while (nCount < nMaxNodes_2) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(GetChild(),aParent); 688*cdf0e10cSrcweir Insert(0,(*aParent)[nParentNodePos]); 689*cdf0e10cSrcweir (*aParent)[nParentNodePos] = (*xPage)[xPage->Count()-1]; 690*cdf0e10cSrcweir xPage->Remove(xPage->Count()-1); 691*cdf0e10cSrcweir } 692*cdf0e10cSrcweir SetChild((*aParent)[nParentNodePos].GetChild()); 693*cdf0e10cSrcweir (*aParent)[nParentNodePos].SetChild(this,aParent); 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir aParent->SetModified(sal_True); 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir //================================================================== 701*cdf0e10cSrcweir // ONDXNode 702*cdf0e10cSrcweir //================================================================== 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir //------------------------------------------------------------------ 705*cdf0e10cSrcweir void ONDXNode::Read(SvStream &rStream, ODbaseIndex& rIndex) 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir rStream >> aKey.nRecord; // schluessel 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir if (rIndex.getHeader().db_keytype) 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir double aDbl; 712*cdf0e10cSrcweir rStream >> aDbl; 713*cdf0e10cSrcweir aKey = ONDXKey(aDbl,aKey.nRecord); 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir else 716*cdf0e10cSrcweir { 717*cdf0e10cSrcweir ByteString aBuf; 718*cdf0e10cSrcweir sal_uInt16 nLen = rIndex.getHeader().db_keylen; 719*cdf0e10cSrcweir char* pStr = aBuf.AllocBuffer(nLen+1); 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir rStream.Read(pStr,nLen); 722*cdf0e10cSrcweir pStr[nLen] = 0; 723*cdf0e10cSrcweir aBuf.ReleaseBufferAccess(); 724*cdf0e10cSrcweir aBuf.EraseTrailingChars(); 725*cdf0e10cSrcweir 726*cdf0e10cSrcweir // aKey = ONDXKey((aBuf,rIndex.GetDBFConnection()->GetCharacterSet()) ,aKey.nRecord); 727*cdf0e10cSrcweir aKey = ONDXKey(::rtl::OUString(aBuf.GetBuffer(),aBuf.Len(),rIndex.m_pTable->getConnection()->getTextEncoding()) ,aKey.nRecord); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir rStream >> aChild; 730*cdf0e10cSrcweir } 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir union NodeData 733*cdf0e10cSrcweir { 734*cdf0e10cSrcweir double aDbl; 735*cdf0e10cSrcweir char aData[128]; 736*cdf0e10cSrcweir } aNodeData; 737*cdf0e10cSrcweir //------------------------------------------------------------------ 738*cdf0e10cSrcweir void ONDXNode::Write(SvStream &rStream, const ONDXPage& rPage) const 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir const ODbaseIndex& rIndex = rPage.GetIndex(); 741*cdf0e10cSrcweir if (!rIndex.isUnique() || rPage.IsLeaf()) 742*cdf0e10cSrcweir rStream << (sal_uInt32)aKey.nRecord; // schluessel 743*cdf0e10cSrcweir else 744*cdf0e10cSrcweir rStream << (sal_uInt32)0; // schluessel 745*cdf0e10cSrcweir 746*cdf0e10cSrcweir if (rIndex.getHeader().db_keytype) // double 747*cdf0e10cSrcweir { 748*cdf0e10cSrcweir if (aKey.getValue().isNull()) 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir memset(aNodeData.aData,0,rIndex.getHeader().db_keylen); 751*cdf0e10cSrcweir rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen); 752*cdf0e10cSrcweir } 753*cdf0e10cSrcweir else 754*cdf0e10cSrcweir rStream << (double) aKey.getValue(); 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir else 757*cdf0e10cSrcweir { 758*cdf0e10cSrcweir memset(aNodeData.aData,0x20,rIndex.getHeader().db_keylen); 759*cdf0e10cSrcweir if (!aKey.getValue().isNull()) 760*cdf0e10cSrcweir { 761*cdf0e10cSrcweir ::rtl::OUString sValue = aKey.getValue(); 762*cdf0e10cSrcweir ByteString aText(sValue.getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()); 763*cdf0e10cSrcweir strncpy(aNodeData.aData,aText.GetBuffer(),std::min(rIndex.getHeader().db_keylen, aText.Len())); 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen); 766*cdf0e10cSrcweir } 767*cdf0e10cSrcweir rStream << aChild; 768*cdf0e10cSrcweir } 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir //------------------------------------------------------------------ 772*cdf0e10cSrcweir ONDXPagePtr& ONDXNode::GetChild(ODbaseIndex* pIndex, ONDXPage* pParent) 773*cdf0e10cSrcweir { 774*cdf0e10cSrcweir if (!aChild.Is() && pIndex) 775*cdf0e10cSrcweir { 776*cdf0e10cSrcweir aChild = pIndex->CreatePage(aChild.GetPagePos(),pParent,aChild.HasPage()); 777*cdf0e10cSrcweir } 778*cdf0e10cSrcweir return aChild; 779*cdf0e10cSrcweir } 780*cdf0e10cSrcweir 781*cdf0e10cSrcweir //================================================================== 782*cdf0e10cSrcweir // ONDXKey 783*cdf0e10cSrcweir //================================================================== 784*cdf0e10cSrcweir //------------------------------------------------------------------ 785*cdf0e10cSrcweir sal_Bool ONDXKey::IsText(sal_Int32 eType) 786*cdf0e10cSrcweir { 787*cdf0e10cSrcweir return eType == DataType::VARCHAR || eType == DataType::CHAR; 788*cdf0e10cSrcweir } 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir //------------------------------------------------------------------ 791*cdf0e10cSrcweir StringCompare ONDXKey::Compare(const ONDXKey& rKey) const 792*cdf0e10cSrcweir { 793*cdf0e10cSrcweir // DBG_ASSERT(is(), "Falscher Indexzugriff"); 794*cdf0e10cSrcweir StringCompare eResult; 795*cdf0e10cSrcweir 796*cdf0e10cSrcweir if (getValue().isNull()) 797*cdf0e10cSrcweir { 798*cdf0e10cSrcweir if (rKey.getValue().isNull() || (rKey.IsText(getDBType()) && !rKey.getValue().getString().getLength())) 799*cdf0e10cSrcweir eResult = COMPARE_EQUAL; 800*cdf0e10cSrcweir else 801*cdf0e10cSrcweir eResult = COMPARE_LESS; 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir else if (rKey.getValue().isNull()) 804*cdf0e10cSrcweir { 805*cdf0e10cSrcweir if (getValue().isNull() || (IsText(getDBType()) && !getValue().getString().getLength())) 806*cdf0e10cSrcweir eResult = COMPARE_EQUAL; 807*cdf0e10cSrcweir else 808*cdf0e10cSrcweir eResult = COMPARE_GREATER; 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir else if (IsText(getDBType())) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir sal_Int32 nRes = getValue().getString().compareTo(rKey.getValue()); 813*cdf0e10cSrcweir eResult = (nRes > 0) ? COMPARE_GREATER : (nRes == 0) ? COMPARE_EQUAL : COMPARE_LESS; 814*cdf0e10cSrcweir } 815*cdf0e10cSrcweir else 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir double m = getValue(),n = rKey.getValue(); 818*cdf0e10cSrcweir eResult = (m > n) ? COMPARE_GREATER : (n == m) ? COMPARE_EQUAL : COMPARE_LESS; 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir // Record vergleich, wenn Index !Unique 822*cdf0e10cSrcweir if (eResult == COMPARE_EQUAL && nRecord && rKey.nRecord) 823*cdf0e10cSrcweir eResult = (nRecord > rKey.nRecord) ? COMPARE_GREATER : 824*cdf0e10cSrcweir (nRecord == rKey.nRecord) ? COMPARE_EQUAL : COMPARE_LESS; 825*cdf0e10cSrcweir 826*cdf0e10cSrcweir return eResult; 827*cdf0e10cSrcweir } 828*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 829*cdf0e10cSrcweir void ONDXKey::setValue(const ORowSetValue& _rVal) 830*cdf0e10cSrcweir { 831*cdf0e10cSrcweir xValue = _rVal; 832*cdf0e10cSrcweir } 833*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 834*cdf0e10cSrcweir const ORowSetValue& ONDXKey::getValue() const 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir return xValue; 837*cdf0e10cSrcweir } 838*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 839*cdf0e10cSrcweir SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPagePtr& rPage) 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir rStream >> rPage.nPagePos; 842*cdf0e10cSrcweir return rStream; 843*cdf0e10cSrcweir } 844*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 845*cdf0e10cSrcweir SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPagePtr& rPage) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir rStream << rPage.nPagePos; 848*cdf0e10cSrcweir return rStream; 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 851*cdf0e10cSrcweir //================================================================== 852*cdf0e10cSrcweir // ONDXPagePtr 853*cdf0e10cSrcweir //================================================================== 854*cdf0e10cSrcweir //------------------------------------------------------------------ 855*cdf0e10cSrcweir ONDXPagePtr::ONDXPagePtr(const ONDXPagePtr& rRef) 856*cdf0e10cSrcweir :ONDXPageRef(rRef) 857*cdf0e10cSrcweir ,nPagePos(rRef.nPagePos) 858*cdf0e10cSrcweir { 859*cdf0e10cSrcweir } 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir //------------------------------------------------------------------ 862*cdf0e10cSrcweir ONDXPagePtr::ONDXPagePtr(ONDXPage* pRefPage) 863*cdf0e10cSrcweir :ONDXPageRef(pRefPage) 864*cdf0e10cSrcweir ,nPagePos(0) 865*cdf0e10cSrcweir { 866*cdf0e10cSrcweir if (pRefPage) 867*cdf0e10cSrcweir nPagePos = pRefPage->GetPagePos(); 868*cdf0e10cSrcweir } 869*cdf0e10cSrcweir //------------------------------------------------------------------ 870*cdf0e10cSrcweir ONDXPagePtr& ONDXPagePtr::operator=(const ONDXPagePtr& rRef) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir ONDXPageRef::operator=(rRef); 873*cdf0e10cSrcweir nPagePos = rRef.nPagePos; 874*cdf0e10cSrcweir return *this; 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir 877*cdf0e10cSrcweir //------------------------------------------------------------------ 878*cdf0e10cSrcweir ONDXPagePtr& ONDXPagePtr::operator= (ONDXPage* pRef) 879*cdf0e10cSrcweir { 880*cdf0e10cSrcweir ONDXPageRef::operator=(pRef); 881*cdf0e10cSrcweir nPagePos = (pRef) ? pRef->GetPagePos() : 0; 882*cdf0e10cSrcweir return *this; 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 885*cdf0e10cSrcweir static sal_uInt32 nValue; 886*cdf0e10cSrcweir //------------------------------------------------------------------ 887*cdf0e10cSrcweir SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPage& rPage) 888*cdf0e10cSrcweir { 889*cdf0e10cSrcweir rStream.Seek(rPage.GetPagePos() * PAGE_SIZE); 890*cdf0e10cSrcweir rStream >> nValue >> rPage.aChild; 891*cdf0e10cSrcweir rPage.nCount = sal_uInt16(nValue); 892*cdf0e10cSrcweir 893*cdf0e10cSrcweir // DBG_ASSERT(rPage.nCount && rPage.nCount < rPage.GetIndex().GetMaxNodes(), "Falscher Count"); 894*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < rPage.nCount; i++) 895*cdf0e10cSrcweir rPage[i].Read(rStream, rPage.GetIndex()); 896*cdf0e10cSrcweir return rStream; 897*cdf0e10cSrcweir } 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir //------------------------------------------------------------------ 900*cdf0e10cSrcweir SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPage& rPage) 901*cdf0e10cSrcweir { 902*cdf0e10cSrcweir // Seite existiert noch nicht 903*cdf0e10cSrcweir sal_uIntPtr nSize = (rPage.GetPagePos() + 1) * PAGE_SIZE; 904*cdf0e10cSrcweir if (nSize > rStream.Seek(STREAM_SEEK_TO_END)) 905*cdf0e10cSrcweir { 906*cdf0e10cSrcweir rStream.SetStreamSize(nSize); 907*cdf0e10cSrcweir rStream.Seek(rPage.GetPagePos() * PAGE_SIZE); 908*cdf0e10cSrcweir 909*cdf0e10cSrcweir char aEmptyData[PAGE_SIZE]; 910*cdf0e10cSrcweir memset(aEmptyData,0x00,PAGE_SIZE); 911*cdf0e10cSrcweir rStream.Write((sal_uInt8*)aEmptyData,PAGE_SIZE); 912*cdf0e10cSrcweir } 913*cdf0e10cSrcweir sal_uIntPtr nCurrentPos = rStream.Seek(rPage.GetPagePos() * PAGE_SIZE); 914*cdf0e10cSrcweir OSL_UNUSED( nCurrentPos ); 915*cdf0e10cSrcweir 916*cdf0e10cSrcweir nValue = rPage.nCount; 917*cdf0e10cSrcweir rStream << nValue << rPage.aChild; 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir sal_uInt16 i = 0; 920*cdf0e10cSrcweir for (; i < rPage.nCount; i++) 921*cdf0e10cSrcweir rPage[i].Write(rStream, rPage); 922*cdf0e10cSrcweir 923*cdf0e10cSrcweir // check if we have to fill the stream with '\0' 924*cdf0e10cSrcweir if(i < rPage.rIndex.getHeader().db_maxkeys) 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir sal_uIntPtr nTell = rStream.Tell() % PAGE_SIZE; 927*cdf0e10cSrcweir sal_uInt16 nBufferSize = rStream.GetBufferSize(); 928*cdf0e10cSrcweir sal_uIntPtr nRemainSize = nBufferSize - nTell; 929*cdf0e10cSrcweir if ( nRemainSize <= nBufferSize ) 930*cdf0e10cSrcweir { 931*cdf0e10cSrcweir char* pEmptyData = new char[nRemainSize]; 932*cdf0e10cSrcweir memset(pEmptyData,0x00,nRemainSize); 933*cdf0e10cSrcweir rStream.Write((sal_uInt8*)pEmptyData,nRemainSize); 934*cdf0e10cSrcweir rStream.Seek(nTell); 935*cdf0e10cSrcweir delete [] pEmptyData; 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir return rStream; 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 941*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 942*cdf0e10cSrcweir //------------------------------------------------------------------ 943*cdf0e10cSrcweir void ONDXPage::PrintPage() 944*cdf0e10cSrcweir { 945*cdf0e10cSrcweir DBG_TRACE4("\nSDB: -----------Page: %d Parent: %d Count: %d Child: %d-----", 946*cdf0e10cSrcweir nPagePos, HasParent() ? aParent->GetPagePos() : 0 ,nCount, aChild.GetPagePos()); 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; i++) 949*cdf0e10cSrcweir { 950*cdf0e10cSrcweir ONDXNode rNode = (*this)[i]; 951*cdf0e10cSrcweir ONDXKey& rKey = rNode.GetKey(); 952*cdf0e10cSrcweir if (!IsLeaf()) 953*cdf0e10cSrcweir rNode.GetChild(&rIndex, this); 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir if (rKey.getValue().isNull()) 956*cdf0e10cSrcweir { 957*cdf0e10cSrcweir DBG_TRACE2("SDB: [%d,NULL,%d]",rKey.GetRecord(), rNode.GetChild().GetPagePos()); 958*cdf0e10cSrcweir } 959*cdf0e10cSrcweir else if (rIndex.getHeader().db_keytype) 960*cdf0e10cSrcweir { 961*cdf0e10cSrcweir DBG_TRACE3("SDB: [%d,%f,%d]",rKey.GetRecord(), rKey.getValue().getDouble(),rNode.GetChild().GetPagePos()); 962*cdf0e10cSrcweir } 963*cdf0e10cSrcweir else 964*cdf0e10cSrcweir { 965*cdf0e10cSrcweir DBG_TRACE3("SDB: [%d,%s,%d]",rKey.GetRecord(), (const char* )ByteString(rKey.getValue().getString().getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()).GetBuffer(),rNode.GetChild().GetPagePos()); 966*cdf0e10cSrcweir } 967*cdf0e10cSrcweir } 968*cdf0e10cSrcweir DBG_TRACE("SDB: -----------------------------------------------\n"); 969*cdf0e10cSrcweir if (!IsLeaf()) 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 972*cdf0e10cSrcweir GetChild(&rIndex)->PrintPage(); 973*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; i++) 974*cdf0e10cSrcweir { 975*cdf0e10cSrcweir ONDXNode rNode = (*this)[i]; 976*cdf0e10cSrcweir rNode.GetChild(&rIndex,this)->PrintPage(); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir #endif 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir DBG_TRACE("SDB: ===============================================\n"); 981*cdf0e10cSrcweir } 982*cdf0e10cSrcweir #endif 983*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 984*cdf0e10cSrcweir sal_Bool ONDXPage::IsFull() const 985*cdf0e10cSrcweir { 986*cdf0e10cSrcweir return Count() == rIndex.getHeader().db_maxkeys; 987*cdf0e10cSrcweir } 988*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 989*cdf0e10cSrcweir //------------------------------------------------------------------ 990*cdf0e10cSrcweir sal_uInt16 ONDXPage::Search(const ONDXKey& rSearch) 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir // binare Suche spaeter 993*cdf0e10cSrcweir sal_uInt16 i = NODE_NOTFOUND; 994*cdf0e10cSrcweir while (++i < Count()) 995*cdf0e10cSrcweir if ((*this)[i].GetKey() == rSearch) 996*cdf0e10cSrcweir break; 997*cdf0e10cSrcweir 998*cdf0e10cSrcweir return (i < Count()) ? i : NODE_NOTFOUND; 999*cdf0e10cSrcweir } 1000*cdf0e10cSrcweir 1001*cdf0e10cSrcweir //------------------------------------------------------------------ 1002*cdf0e10cSrcweir sal_uInt16 ONDXPage::Search(const ONDXPage* pPage) 1003*cdf0e10cSrcweir { 1004*cdf0e10cSrcweir sal_uInt16 i = NODE_NOTFOUND; 1005*cdf0e10cSrcweir while (++i < Count()) 1006*cdf0e10cSrcweir if (((*this)[i]).GetChild() == pPage) 1007*cdf0e10cSrcweir break; 1008*cdf0e10cSrcweir 1009*cdf0e10cSrcweir // wenn nicht gefunden, dann wird davon ausgegangen, dass die Seite selbst 1010*cdf0e10cSrcweir // auf die Page zeigt 1011*cdf0e10cSrcweir return (i < Count()) ? i : NODE_NOTFOUND; 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1014*cdf0e10cSrcweir // laeuft rekursiv 1015*cdf0e10cSrcweir void ONDXPage::SearchAndReplace(const ONDXKey& rSearch, 1016*cdf0e10cSrcweir ONDXKey& rReplace) 1017*cdf0e10cSrcweir { 1018*cdf0e10cSrcweir OSL_ENSURE(rSearch != rReplace,"Invalid here:rSearch == rReplace"); 1019*cdf0e10cSrcweir if (rSearch != rReplace) 1020*cdf0e10cSrcweir { 1021*cdf0e10cSrcweir sal_uInt16 nPos = NODE_NOTFOUND; 1022*cdf0e10cSrcweir ONDXPage* pPage = this; 1023*cdf0e10cSrcweir 1024*cdf0e10cSrcweir while (pPage && (nPos = pPage->Search(rSearch)) == NODE_NOTFOUND) 1025*cdf0e10cSrcweir pPage = pPage->aParent; 1026*cdf0e10cSrcweir 1027*cdf0e10cSrcweir if (pPage) 1028*cdf0e10cSrcweir { 1029*cdf0e10cSrcweir (*pPage)[nPos].GetKey() = rReplace; 1030*cdf0e10cSrcweir pPage->SetModified(sal_True); 1031*cdf0e10cSrcweir } 1032*cdf0e10cSrcweir } 1033*cdf0e10cSrcweir } 1034*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1035*cdf0e10cSrcweir ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 1038*cdf0e10cSrcweir return ppNodes[nPos]; 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir //------------------------------------------------------------------ 1042*cdf0e10cSrcweir const ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) const 1043*cdf0e10cSrcweir { 1044*cdf0e10cSrcweir DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 1045*cdf0e10cSrcweir return ppNodes[nPos]; 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1048*cdf0e10cSrcweir void ONDXPage::Remove(sal_uInt16 nPos) 1049*cdf0e10cSrcweir { 1050*cdf0e10cSrcweir DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 1051*cdf0e10cSrcweir 1052*cdf0e10cSrcweir for (sal_uInt16 i = nPos; i < (nCount-1); i++) 1053*cdf0e10cSrcweir (*this)[i] = (*this)[i+1]; 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir nCount--; 1056*cdf0e10cSrcweir bModified = sal_True; 1057*cdf0e10cSrcweir } 1058*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1059*cdf0e10cSrcweir 1060