LibreOffice Module connectivity (master) 1
dindexnode.hxx
Go to the documentation of this file.
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#pragma once
20
21#include <file/fcode.hxx>
23#include <memory>
24
25#define NODE_NOTFOUND 0xFFFF
26#define DINDEX_PAGE_SIZE 512
27
28class SvStream;
29
30namespace connectivity::dbase
31 {
32
33 class ONDXNode;
34 class ODbaseIndex;
35
36 // Index Key
37
39 class ONDXKey : public ONDXKey_BASE
40 {
41 friend class ONDXNode;
42 sal_uInt32 nRecord; /* Record pointer */
43 ORowSetValue xValue; /* Key values */
44
45 public:
46 ONDXKey();
47 ONDXKey(ORowSetValue aVal, sal_Int32 eType, sal_uInt32 nRec);
48 ONDXKey(const OUString& aStr, sal_uInt32 nRec);
49 ONDXKey(double aVal, sal_uInt32 nRec);
50
51 inline ONDXKey(const ONDXKey& rKey);
52
53 inline ONDXKey& operator= (const ONDXKey& rKey);
54 virtual void setValue(const ORowSetValue& _rVal) override;
55
56 virtual const ORowSetValue& getValue() const override;
57
58 sal_uInt32 GetRecord() const { return nRecord; }
59 void setRecord(sal_uInt32 _nRec) { nRecord = _nRec; }
60 void ResetRecord() { nRecord = 0; }
61
62 bool operator == (const ONDXKey& rKey) const;
63 bool operator != (const ONDXKey& rKey) const;
64 bool operator < (const ONDXKey& rKey) const;
65 bool operator <= (const ONDXKey& rKey) const;
66 bool operator > (const ONDXKey& rKey) const;
67
68 static bool IsText(sal_Int32 eType);
69
70 private:
71 int Compare(const ONDXKey& rKey) const;
72 };
73
74
75 class ONDXPage;
76
77 // Index Page Pointer
78 // This is ref-count pointer class
80 {
81 friend SvStream& WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr&);
83
85 sal_uInt32 nPagePos; // Position in the index file
86
87 public:
89 ONDXPagePtr(ONDXPagePtr&& rObj) noexcept;
90 ONDXPagePtr(ONDXPagePtr const & rRef);
91 ONDXPagePtr(ONDXPage* pRefPage);
93 void Clear();
94 ONDXPagePtr& operator=(ONDXPagePtr const & rRef);
96 bool Is() const { return mpPage != nullptr; }
97
98 ONDXPage * operator ->() const { assert(mpPage != nullptr); return mpPage; }
99 operator ONDXPage *() const { return mpPage; }
100
101 sal_uInt32 GetPagePos() const {return nPagePos;}
102 bool HasPage() const {return nPagePos != 0;}
103 };
104
105 // Index Page
106 // This is a ref-counted class, with re-cycling
108 {
109 friend class ODbaseIndex;
110 friend class ONDXPagePtr;
111
112 friend SvStream& WriteONDXPage(SvStream &rStream, const ONDXPage&);
114
115 // work around a clang 3.5 optimization bug: if the bNoDelete is *first*
116 // it mis-compiles "if (--nRefCount == 0)" and never deletes any object
117 unsigned int nRefCount : 31;
118 // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
119 unsigned int bNoDelete : 1;
120 sal_uInt32 nPagePos; // Position in the index file
121 bool bModified : 1;
122 sal_uInt16 nCount;
123
124 ONDXPagePtr aParent, // Parent page
125 aChild; // Pointer to the right child page
127 std::unique_ptr<ONDXNode[]>
128 ppNodes; // Array of nodes
129
130 public:
131 // Node operations
132 sal_uInt16 Count() const {return nCount;}
133
134 bool Insert(ONDXNode& rNode, sal_uInt32 nRowsLeft = 0);
135 bool Insert(sal_uInt16 nIndex, ONDXNode& rNode);
136 bool Append(ONDXNode& rNode);
137 void Delete(sal_uInt16);
138 void Remove(sal_uInt16);
139 void Release(bool bSave = true);
140 void ReleaseFull();
141
142 // Split and merge
143 ONDXNode Split(ONDXPage& rPage);
144 void Merge(sal_uInt16 nParentNodePos, const ONDXPagePtr& xPage);
145
146 // Access operators
147 ONDXNode& operator[] (sal_uInt16 nPos);
148 const ONDXNode& operator[] (sal_uInt16 nPos) const;
149
150 bool IsRoot() const;
151 bool IsLeaf() const;
152 bool IsModified() const;
153 bool HasParent() const;
154
155 bool IsFull() const;
156
157 sal_uInt32 GetPagePos() const {return nPagePos;}
158 ONDXPagePtr& GetChild(ODbaseIndex const * pIndex = nullptr);
159
160 // Parent does not need to be reloaded
161 const ONDXPagePtr& GetParent() const;
163 const ODbaseIndex& GetIndex() const {return rIndex;}
164
165 // Setting the child, via reference to retain the PagePos
166 void SetChild(ONDXPagePtr aCh);
167 void SetParent(ONDXPagePtr aPa);
168
169 sal_uInt16 Search(const ONDXKey& rSearch);
170 sal_uInt16 Search(const ONDXPage* pPage);
171 void SearchAndReplace(const ONDXKey& rSearch, ONDXKey const & rReplace);
172
173 protected:
174 ONDXPage(ODbaseIndex& rIndex, sal_uInt32 nPos, ONDXPage*);
175 ~ONDXPage();
176
177 void ReleaseRef();
178 void QueryDelete();
180 {
181 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
182 ++nRefCount;
183 }
185 {
186 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
187 if( bNoDelete )
188 bNoDelete = 0;
189 ++nRefCount;
190 }
191
192 void SetModified(bool bMod) {bModified = bMod;}
193 void SetPagePos(sal_uInt32 nPage) {nPagePos = nPage;}
194
195 bool Find(const ONDXKey&); // Descend recursively
196 sal_uInt16 FindPos(const ONDXKey& rKey) const;
197
198#if OSL_DEBUG_LEVEL > 1
199 void PrintPage();
200#endif
201 };
202
203 SvStream& WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr&);
204 SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
205
206 inline bool ONDXPage::IsRoot() const {return !aParent.Is();}
207 inline bool ONDXPage::IsLeaf() const {return !aChild.HasPage();}
208 inline bool ONDXPage::IsModified() const {return bModified;}
209 inline bool ONDXPage::HasParent() const {return aParent.Is();}
210 inline const ONDXPagePtr& ONDXPage::GetParent() const {return aParent;}
211
213 {
214 aParent = aPa;
215 }
216
218 {
219 aChild = aCh;
220 if (aChild.Is())
221 aChild->SetParent(this);
222 }
223 SvStream& operator >> (SvStream &rStream, ONDXPage& rPage);
224 SvStream& WriteONDXPage(SvStream &rStream, const ONDXPage& rPage);
225
226
227 // Index Node
228
230 {
231 friend class ONDXPage;
232 ONDXPagePtr aChild; /* Next page reference */
234
235 public:
237 ONDXNode(const ONDXKey& rKey)
238 :aKey(rKey) {}
239
240 // Does the node point to a page?
241 bool HasChild() const {return aChild.HasPage();}
242 // If an index is provided, we may be able to retrieve the page
243 ONDXPagePtr& GetChild(ODbaseIndex* pIndex = nullptr, ONDXPage* = nullptr);
244
245 const ONDXKey& GetKey() const { return aKey;}
246 ONDXKey& GetKey() { return aKey;}
247
248 // Setting the child, via reference to retain the PagePos
249 void SetChild(ONDXPagePtr aCh = ONDXPagePtr(), ONDXPage* = nullptr);
250
251 void Write(SvStream &rStream, const ONDXPage& rPage) const;
252 void Read(SvStream &rStream, ODbaseIndex const &);
253 };
254
255 inline ONDXKey::ONDXKey(const ONDXKey& rKey)
256 : ONDXKey_BASE(rKey.getDBType())
257 ,nRecord(rKey.nRecord)
258 ,xValue(rKey.xValue)
259 {
260 }
261
262 inline ONDXKey& ONDXKey::operator=(const ONDXKey& rKey)
263 {
264 if(&rKey == this)
265 return *this;
266
267 xValue = rKey.xValue;
268 nRecord = rKey.nRecord;
269 m_eDBType = rKey.getDBType();
270 return *this;
271 }
272
273 inline bool ONDXKey::operator == (const ONDXKey& rKey) const
274 {
275 if(&rKey == this)
276 return true;
277 return Compare(rKey) == 0;
278 }
279 inline bool ONDXKey::operator != (const ONDXKey& rKey) const
280 {
281 return !operator== (rKey);
282 }
283 inline bool ONDXKey::operator < (const ONDXKey& rKey) const
284 {
285 return Compare(rKey) < 0;
286 }
287 inline bool ONDXKey::operator > (const ONDXKey& rKey) const
288 {
289 return Compare(rKey) > 0;
290 }
291 inline bool ONDXKey::operator <= (const ONDXKey& rKey) const
292 {
293 return !operator > (rKey);
294 }
295
296 inline void ONDXNode::SetChild(ONDXPagePtr aCh, ONDXPage* pParent)
297 {
298 aChild = aCh;
299 if (aChild.Is())
300 aChild->SetParent(pParent);
301 }
302
303}
304
305
306
307/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual const ORowSetValue & getValue() const override
Definition: dindexnode.cxx:787
virtual void setValue(const ORowSetValue &_rVal) override
Definition: dindexnode.cxx:782
bool operator==(const ONDXKey &rKey) const
Definition: dindexnode.hxx:273
int Compare(const ONDXKey &rKey) const
Definition: dindexnode.cxx:744
bool operator<(const ONDXKey &rKey) const
Definition: dindexnode.hxx:283
void setRecord(sal_uInt32 _nRec)
Definition: dindexnode.hxx:59
ONDXKey & operator=(const ONDXKey &rKey)
Definition: dindexnode.hxx:262
static bool IsText(sal_Int32 eType)
Definition: dindexnode.cxx:738
sal_uInt32 GetRecord() const
Definition: dindexnode.hxx:58
bool operator>(const ONDXKey &rKey) const
Definition: dindexnode.hxx:287
bool operator!=(const ONDXKey &rKey) const
Definition: dindexnode.hxx:279
bool operator<=(const ONDXKey &rKey) const
Definition: dindexnode.hxx:291
const ONDXKey & GetKey() const
Definition: dindexnode.hxx:245
void SetChild(ONDXPagePtr aCh=ONDXPagePtr(), ONDXPage *=nullptr)
Definition: dindexnode.hxx:296
void Read(SvStream &rStream, ODbaseIndex const &)
Definition: dindexnode.cxx:661
ONDXNode(const ONDXKey &rKey)
Definition: dindexnode.hxx:237
ONDXPagePtr & GetChild(ODbaseIndex *pIndex=nullptr, ONDXPage *=nullptr)
Definition: dindexnode.cxx:725
void Write(SvStream &rStream, const ONDXPage &rPage) const
Definition: dindexnode.cxx:685
ONDXPagePtr & operator=(ONDXPagePtr const &rRef)
Definition: dindexnode.cxx:850
ONDXPage * operator->() const
Definition: dindexnode.hxx:98
friend SvStream & WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr &)
friend SvStream & operator>>(SvStream &rStream, ONDXPagePtr &)
bool Append(ONDXNode &rNode)
Definition: dindexnode.cxx:335
ONDXPagePtr & GetChild(ODbaseIndex const *pIndex=nullptr)
Definition: dindexnode.cxx:129
void SetChild(ONDXPagePtr aCh)
Definition: dindexnode.hxx:217
sal_uInt32 GetPagePos() const
Definition: dindexnode.hxx:157
sal_uInt16 Search(const ONDXKey &rSearch)
Definition: dindexnode.cxx:973
sal_uInt16 Count() const
Definition: dindexnode.hxx:132
ONDXNode Split(ONDXPage &rPage)
Definition: dindexnode.cxx:426
ONDXPage(ODbaseIndex &rIndex, sal_uInt32 nPos, ONDXPage *)
Definition: dindexnode.cxx:68
void SetParent(ONDXPagePtr aPa)
Definition: dindexnode.hxx:212
void SetPagePos(sal_uInt32 nPage)
Definition: dindexnode.hxx:193
ONDXNode & operator[](sal_uInt16 nPos)
friend SvStream & operator>>(SvStream &rStream, ONDXPage &)
bool Find(const ONDXKey &)
Definition: dindexnode.cxx:150
sal_uInt16 FindPos(const ONDXKey &rKey) const
Definition: dindexnode.cxx:139
void SearchAndReplace(const ONDXKey &rSearch, ONDXKey const &rReplace)
Definition: dindexnode.cxx:997
void Merge(sal_uInt16 nParentNodePos, const ONDXPagePtr &xPage)
Definition: dindexnode.cxx:476
bool Insert(ONDXNode &rNode, sal_uInt32 nRowsLeft=0)
Definition: dindexnode.cxx:184
std::unique_ptr< ONDXNode[]> ppNodes
Definition: dindexnode.hxx:128
void Release(bool bSave=true)
Definition: dindexnode.cxx:341
const ODbaseIndex & GetIndex() const
Definition: dindexnode.hxx:163
friend SvStream & WriteONDXPage(SvStream &rStream, const ONDXPage &)
const ONDXPagePtr & GetParent() const
Definition: dindexnode.hxx:210
sal_Int32 getDBType() const
Definition: fcode.hxx:68
SvStream & operator>>(SvStream &rStream, ODbaseIndex &)
Definition: DIndex.cxx:333
SvStream & WriteONDXPage(SvStream &rStream, const ONDXPage &rPage)
Definition: dindexnode.cxx:882
file::OOperand ONDXKey_BASE
Definition: dindexnode.hxx:34
SvStream & WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr &)
Definition: dindexnode.cxx:798