Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef INCLUDED_CONNECTIVITY_SOURCE_INC_DBASE_DINDEXNODE_HXX
20 : #define INCLUDED_CONNECTIVITY_SOURCE_INC_DBASE_DINDEXNODE_HXX
21 :
22 : #include "file/fcode.hxx"
23 : #include "file/FTable.hxx"
24 : #include <connectivity/FValue.hxx>
25 : #include <rtl/ref.hxx>
26 : #include <tools/stream.hxx>
27 : #include <vector>
28 :
29 : #define NODE_NOTFOUND 0xFFFF
30 : #define DINDEX_PAGE_SIZE 512
31 :
32 : namespace connectivity
33 : {
34 : namespace dbase
35 : {
36 :
37 : class ONDXNode;
38 : class ODbaseIndex;
39 :
40 : // Index Key
41 :
42 : typedef file::OOperand ONDXKey_BASE;
43 0 : class ONDXKey : public ONDXKey_BASE
44 : {
45 : friend class ONDXNode;
46 : sal_uInt32 nRecord; /* Record pointer */
47 : ORowSetValue xValue; /* Key values */
48 :
49 : public:
50 : ONDXKey(sal_uInt32 nRec=0);
51 : ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec);
52 : ONDXKey(const OUString& aStr, sal_uInt32 nRec = 0);
53 : ONDXKey(double aVal, sal_uInt32 nRec = 0);
54 :
55 : inline ONDXKey(const ONDXKey& rKey);
56 :
57 : inline ONDXKey& operator= (const ONDXKey& rKey);
58 : virtual void setValue(const ORowSetValue& _rVal) SAL_OVERRIDE;
59 :
60 : virtual const ORowSetValue& getValue() const SAL_OVERRIDE;
61 :
62 0 : sal_uInt32 GetRecord() const { return nRecord; }
63 0 : void setRecord(sal_uInt32 _nRec) { nRecord = _nRec; }
64 0 : void ResetRecord() { nRecord = 0; }
65 :
66 : bool operator == (const ONDXKey& rKey) const;
67 : bool operator != (const ONDXKey& rKey) const;
68 : bool operator < (const ONDXKey& rKey) const;
69 : bool operator <= (const ONDXKey& rKey) const;
70 : bool operator > (const ONDXKey& rKey) const;
71 : bool operator >= (const ONDXKey& rKey) const;
72 :
73 : bool Load (SvFileStream& rStream, bool bText);
74 : bool Write(SvFileStream& rStream, bool bText);
75 :
76 : static bool IsText(sal_Int32 eType);
77 :
78 : private:
79 : int Compare(const ONDXKey& rKey) const;
80 : };
81 :
82 :
83 :
84 :
85 :
86 : class ONDXPage;
87 :
88 : // Index Page Pointer
89 : // This is ref-count pointer class
90 : class ONDXPagePtr
91 : {
92 : friend SvStream& WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr&);
93 : friend SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
94 :
95 : ONDXPage* mpPage;
96 : sal_uInt32 nPagePos; // Position in the index file
97 :
98 : public:
99 0 : ONDXPagePtr(sal_uInt32 nPos = 0) : mpPage(0), nPagePos(nPos) {}
100 : ONDXPagePtr(const ONDXPagePtr& rRef);
101 : ONDXPagePtr(ONDXPage* pRefPage);
102 : inline ~ONDXPagePtr();
103 :
104 0 : sal_uInt32 GetPagePos() const {return nPagePos;}
105 0 : bool HasPage() const {return nPagePos != 0;}
106 :
107 0 : operator ONDXPage *() const { return mpPage; }
108 0 : ONDXPage * operator ->() const { assert(mpPage != 0); return mpPage; }
109 0 : bool Is() const { return mpPage != 0; }
110 : inline void Clear();
111 : ONDXPagePtr& operator=(const ONDXPagePtr& rRef);
112 : };
113 :
114 : // Index Page
115 : // This is a ref-counted class, with re-cycling
116 : class ONDXPage
117 : {
118 : friend class ODbaseIndex;
119 : friend class ONDXPagePtr;
120 :
121 : friend SvStream& WriteONDXPage(SvStream &rStream, const ONDXPage&);
122 : friend SvStream& operator >> (SvStream &rStream, ONDXPage&);
123 :
124 : // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
125 : unsigned int bNoDelete : 1;
126 : unsigned int nRefCount : 31;
127 : sal_uInt32 nPagePos; // Position in the index file
128 : bool bModified : 1;
129 : sal_uInt16 nCount;
130 :
131 : ONDXPagePtr aParent, // Parent page
132 : aChild; // Pointer to the right child page
133 : ODbaseIndex& rIndex;
134 : ONDXNode* ppNodes; // Array of nodes
135 :
136 : public:
137 : // Node operations
138 0 : sal_uInt16 Count() const {return nCount;}
139 :
140 : bool Insert(ONDXNode& rNode, sal_uInt32 nRowsLeft = 0);
141 : bool Insert(sal_uInt16 nIndex, ONDXNode& rNode);
142 : bool Append(ONDXNode& rNode);
143 : bool Delete(sal_uInt16);
144 : void Remove(sal_uInt16);
145 : void Release(bool bSave = true);
146 : void ReleaseFull(bool bSave = true);
147 :
148 : // Split and merge
149 : ONDXNode Split(ONDXPage& rPage);
150 : void Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage);
151 :
152 : // Access operators
153 : ONDXNode& operator[] (sal_uInt16 nPos);
154 : const ONDXNode& operator[] (sal_uInt16 nPos) const;
155 :
156 : bool IsRoot() const;
157 : bool IsLeaf() const;
158 : bool IsModified() const;
159 : bool HasParent();
160 : bool HasChild() const;
161 :
162 : bool IsFull() const;
163 :
164 0 : sal_uInt32 GetPagePos() const {return nPagePos;}
165 : ONDXPagePtr& GetChild(ODbaseIndex* pIndex = 0);
166 :
167 : // Parent does not need to be reloaded
168 : ONDXPagePtr GetParent();
169 0 : ODbaseIndex& GetIndex() {return rIndex;}
170 0 : const ODbaseIndex& GetIndex() const {return rIndex;}
171 :
172 : // Setting the child, via reference to retain the PagePos
173 : void SetChild(ONDXPagePtr aCh);
174 : void SetParent(ONDXPagePtr aPa);
175 :
176 : sal_uInt16 Search(const ONDXKey& rSearch);
177 : sal_uInt16 Search(const ONDXPage* pPage);
178 : void SearchAndReplace(const ONDXKey& rSearch, ONDXKey& rReplace);
179 :
180 : protected:
181 : ONDXPage(ODbaseIndex& rIndex, sal_uInt32 nPos, ONDXPage* = NULL);
182 : ~ONDXPage();
183 :
184 : void ReleaseRef();
185 : void QueryDelete();
186 0 : void AddNextRef()
187 : {
188 : assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
189 0 : ++nRefCount;
190 0 : }
191 0 : void AddFirstRef()
192 : {
193 : assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
194 0 : if( bNoDelete )
195 0 : bNoDelete = 0;
196 0 : ++nRefCount;
197 0 : }
198 :
199 0 : void SetModified(bool bMod) {bModified = bMod;}
200 0 : void SetPagePos(sal_uInt32 nPage) {nPagePos = nPage;}
201 :
202 : bool Find(const ONDXKey&); // Descend recursively
203 : sal_uInt16 FindPos(const ONDXKey& rKey) const;
204 :
205 : #if OSL_DEBUG_LEVEL > 1
206 : void PrintPage();
207 : #endif
208 : };
209 :
210 0 : inline ONDXPagePtr::~ONDXPagePtr() { if (mpPage != 0) mpPage->ReleaseRef(); }
211 0 : inline void ONDXPagePtr::Clear()
212 : {
213 0 : if (mpPage != 0) {
214 0 : ONDXPage * pRefObj = mpPage;
215 0 : mpPage = 0;
216 0 : pRefObj->ReleaseRef();
217 : }
218 0 : }
219 :
220 : SvStream& WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr&);
221 : SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
222 :
223 0 : inline bool ONDXPage::IsRoot() const {return !aParent.Is();}
224 0 : inline bool ONDXPage::IsLeaf() const {return !aChild.HasPage();}
225 0 : inline bool ONDXPage::IsModified() const {return bModified;}
226 0 : inline bool ONDXPage::HasParent() {return aParent.Is();}
227 : inline bool ONDXPage::HasChild() const {return aChild.HasPage();}
228 0 : inline ONDXPagePtr ONDXPage::GetParent() {return aParent;}
229 :
230 0 : inline void ONDXPage::SetParent(ONDXPagePtr aPa = ONDXPagePtr())
231 : {
232 0 : aParent = aPa;
233 0 : }
234 :
235 0 : inline void ONDXPage::SetChild(ONDXPagePtr aCh = ONDXPagePtr())
236 : {
237 0 : aChild = aCh;
238 0 : if (aChild.Is())
239 0 : aChild->SetParent(this);
240 0 : }
241 : SvStream& operator >> (SvStream &rStream, ONDXPage& rPage);
242 : SvStream& WriteONDXPage(SvStream &rStream, const ONDXPage& rPage);
243 :
244 :
245 : typedef ::std::vector<ONDXPage*> ONDXPageList;
246 :
247 :
248 : // Index Node
249 :
250 0 : class ONDXNode
251 : {
252 : friend class ONDXPage;
253 : ONDXPagePtr aChild; /* Next page reference */
254 : ONDXKey aKey;
255 :
256 : public:
257 0 : ONDXNode(){}
258 0 : ONDXNode(const ONDXKey& rKey,
259 : ONDXPagePtr aPagePtr = ONDXPagePtr())
260 0 : :aChild(aPagePtr),aKey(rKey) {}
261 :
262 : // Does the node point to a page?
263 0 : bool HasChild() const {return aChild.HasPage();}
264 : // If an index is provided, we may be able to retrieve the page
265 : ONDXPagePtr& GetChild(ODbaseIndex* pIndex = NULL, ONDXPage* = NULL);
266 :
267 0 : const ONDXKey& GetKey() const { return aKey;}
268 0 : ONDXKey& GetKey() { return aKey;}
269 :
270 : // Setting the child, via reference to retain the PagePos
271 : void SetChild(ONDXPagePtr aCh = ONDXPagePtr(), ONDXPage* = NULL);
272 : void SetKey(ONDXKey& rKey) {aKey = rKey;}
273 :
274 : void Write(SvStream &rStream, const ONDXPage& rPage) const;
275 : void Read(SvStream &rStream, ODbaseIndex&);
276 : };
277 :
278 : // inline implementation
279 :
280 : // inline ONDXKey::ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec)
281 : // : ONDXKey_BASE(eType)
282 : // , nRecord(nRec),xValue(rVal)
283 : // {
284 : // }
285 :
286 :
287 : // inline ONDXKey::ONDXKey(const OUString& aStr, sal_uInt32 nRec)
288 : // : ONDXKey_BASE(::com::sun::star::sdbc::DataType::VARCHAR)
289 : // ,nRecord(nRec)
290 : // {
291 : // if (aStr.len())
292 : // xValue = aStr;
293 : // }
294 :
295 : // inline ONDXKey::ONDXKey(double aVal, sal_uInt32 nRec)
296 : // : ONDXKey_BASE(::com::sun::star::sdbc::DataType::DOUBLE)
297 : // ,nRecord(nRec)
298 : // ,xValue(aVal)
299 : // {
300 : // }
301 :
302 : // inline ONDXKey::ONDXKey(sal_uInt32 nRec)
303 : // :nRecord(nRec)
304 : // {
305 : // }
306 :
307 0 : inline ONDXKey::ONDXKey(const ONDXKey& rKey)
308 0 : : ONDXKey_BASE(rKey.getDBType())
309 : ,nRecord(rKey.nRecord)
310 0 : ,xValue(rKey.xValue)
311 : {
312 0 : }
313 :
314 0 : inline ONDXKey& ONDXKey::operator=(const ONDXKey& rKey)
315 : {
316 0 : if(&rKey == this)
317 0 : return *this;
318 :
319 0 : xValue = rKey.xValue;
320 0 : nRecord = rKey.nRecord;
321 0 : m_eDBType = rKey.getDBType();
322 0 : return *this;
323 : }
324 :
325 0 : inline bool ONDXKey::operator == (const ONDXKey& rKey) const
326 : {
327 0 : if(&rKey == this)
328 0 : return true;
329 0 : return Compare(rKey) == 0;
330 : }
331 0 : inline bool ONDXKey::operator != (const ONDXKey& rKey) const
332 : {
333 0 : return !operator== (rKey);
334 : }
335 : inline bool ONDXKey::operator < (const ONDXKey& rKey) const
336 : {
337 : return Compare(rKey) < 0;
338 : }
339 0 : inline bool ONDXKey::operator > (const ONDXKey& rKey) const
340 : {
341 0 : return Compare(rKey) > 0;
342 : }
343 0 : inline bool ONDXKey::operator <= (const ONDXKey& rKey) const
344 : {
345 0 : return !operator > (rKey);
346 : }
347 : inline bool ONDXKey::operator >= (const ONDXKey& rKey) const
348 : {
349 : return !operator< (rKey);
350 : }
351 :
352 0 : inline void ONDXNode::SetChild(ONDXPagePtr aCh, ONDXPage* pParent)
353 : {
354 0 : aChild = aCh;
355 0 : if (aChild.Is())
356 0 : aChild->SetParent(pParent);
357 0 : }
358 :
359 : }
360 :
361 : }
362 :
363 :
364 :
365 :
366 : #endif // INCLUDED_CONNECTIVITY_SOURCE_INC_DBASE_DINDEXNODE_HXX
367 :
368 :
369 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|