1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <file/fcode.hxx>
22 #include <connectivity/FValue.hxx>
25 #define NODE_NOTFOUND 0xFFFF
26 #define DINDEX_PAGE_SIZE 512
30 namespace connectivity::dbase
38 typedef file::OOperand ONDXKey_BASE
;
39 class ONDXKey
: public ONDXKey_BASE
41 friend class ONDXNode
;
42 sal_uInt32 nRecord
; /* Record pointer */
43 ORowSetValue xValue
; /* Key values */
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
);
51 inline ONDXKey(const ONDXKey
& rKey
);
53 inline ONDXKey
& operator= (const ONDXKey
& rKey
);
54 virtual void setValue(const ORowSetValue
& _rVal
) override
;
56 virtual const ORowSetValue
& getValue() const override
;
58 sal_uInt32
GetRecord() const { return nRecord
; }
59 void setRecord(sal_uInt32 _nRec
) { nRecord
= _nRec
; }
60 void ResetRecord() { nRecord
= 0; }
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;
68 static bool IsText(sal_Int32 eType
);
71 int Compare(const ONDXKey
& rKey
) const;
78 // This is ref-count pointer class
81 friend SvStream
& WriteONDXPagePtr(SvStream
&rStream
, const ONDXPagePtr
&);
82 friend SvStream
& operator >> (SvStream
&rStream
, ONDXPagePtr
&);
85 sal_uInt32 nPagePos
; // Position in the index file
89 ONDXPagePtr(ONDXPagePtr
&& rObj
) noexcept
;
90 ONDXPagePtr(ONDXPagePtr
const & rRef
);
91 ONDXPagePtr(ONDXPage
* pRefPage
);
94 ONDXPagePtr
& operator=(ONDXPagePtr
const & rRef
);
95 ONDXPagePtr
& operator=(ONDXPagePtr
&& rRef
);
96 bool Is() const { return mpPage
!= nullptr; }
98 ONDXPage
* operator ->() const { assert(mpPage
!= nullptr); return mpPage
; }
99 operator ONDXPage
*() const { return mpPage
; }
101 sal_uInt32
GetPagePos() const {return nPagePos
;}
102 bool HasPage() const {return nPagePos
!= 0;}
106 // This is a ref-counted class, with re-cycling
109 friend class ODbaseIndex
;
110 friend class ONDXPagePtr
;
112 friend SvStream
& WriteONDXPage(SvStream
&rStream
, const ONDXPage
&);
113 friend SvStream
& operator >> (SvStream
&rStream
, ONDXPage
&);
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
124 ONDXPagePtr aParent
, // Parent page
125 aChild
; // Pointer to the right child page
127 std::unique_ptr
<ONDXNode
[]>
128 ppNodes
; // Array of nodes
132 sal_uInt16
Count() const {return nCount
;}
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);
143 ONDXNode
Split(ONDXPage
& rPage
);
144 void Merge(sal_uInt16 nParentNodePos
, const ONDXPagePtr
& xPage
);
147 ONDXNode
& operator[] (sal_uInt16 nPos
);
148 const ONDXNode
& operator[] (sal_uInt16 nPos
) const;
152 bool IsModified() const;
153 bool HasParent() const;
157 sal_uInt32
GetPagePos() const {return nPagePos
;}
158 ONDXPagePtr
& GetChild(ODbaseIndex
const * pIndex
= nullptr);
160 // Parent does not need to be reloaded
161 const ONDXPagePtr
& GetParent() const;
162 ODbaseIndex
& GetIndex() {return rIndex
;}
163 const ODbaseIndex
& GetIndex() const {return rIndex
;}
165 // Setting the child, via reference to retain the PagePos
166 void SetChild(const ONDXPagePtr
& rCh
);
167 void SetParent(const ONDXPagePtr
& rPa
);
169 sal_uInt16
Search(const ONDXKey
& rSearch
);
170 sal_uInt16
Search(const ONDXPage
* pPage
);
171 void SearchAndReplace(const ONDXKey
& rSearch
, ONDXKey
const & rReplace
);
174 ONDXPage(ODbaseIndex
& rIndex
, sal_uInt32 nPos
, ONDXPage
*);
181 assert( nRefCount
< (1 << 30) && "Do not add refs to dead objects" );
186 assert( nRefCount
< (1 << 30) && "Do not add refs to dead objects" );
192 void SetModified(bool bMod
) {bModified
= bMod
;}
193 void SetPagePos(sal_uInt32 nPage
) {nPagePos
= nPage
;}
195 bool Find(const ONDXKey
&); // Descend recursively
196 sal_uInt16
FindPos(const ONDXKey
& rKey
) const;
198 #if OSL_DEBUG_LEVEL > 1
203 SvStream
& WriteONDXPagePtr(SvStream
&rStream
, const ONDXPagePtr
&);
204 SvStream
& operator >> (SvStream
&rStream
, ONDXPagePtr
&);
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
;}
212 inline void ONDXPage::SetParent(const ONDXPagePtr
& rPa
= ONDXPagePtr())
217 inline void ONDXPage::SetChild(const ONDXPagePtr
& rCh
= ONDXPagePtr())
221 aChild
->SetParent(this);
223 SvStream
& operator >> (SvStream
&rStream
, ONDXPage
& rPage
);
224 SvStream
& WriteONDXPage(SvStream
&rStream
, const ONDXPage
& rPage
);
231 friend class ONDXPage
;
232 ONDXPagePtr aChild
; /* Next page reference */
237 ONDXNode(const ONDXKey
& rKey
)
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);
245 const ONDXKey
& GetKey() const { return aKey
;}
246 ONDXKey
& GetKey() { return aKey
;}
248 // Setting the child, via reference to retain the PagePos
249 void SetChild(const ONDXPagePtr
& rCh
= ONDXPagePtr(), ONDXPage
* = nullptr);
251 void Write(SvStream
&rStream
, const ONDXPage
& rPage
) const;
252 void Read(SvStream
&rStream
, ODbaseIndex
const &);
255 inline ONDXKey::ONDXKey(const ONDXKey
& rKey
)
256 : ONDXKey_BASE(rKey
.getDBType())
257 ,nRecord(rKey
.nRecord
)
262 inline ONDXKey
& ONDXKey::operator=(const ONDXKey
& rKey
)
267 xValue
= rKey
.xValue
;
268 nRecord
= rKey
.nRecord
;
269 m_eDBType
= rKey
.getDBType();
273 inline bool ONDXKey::operator == (const ONDXKey
& rKey
) const
277 return Compare(rKey
) == 0;
279 inline bool ONDXKey::operator != (const ONDXKey
& rKey
) const
281 return !operator== (rKey
);
283 inline bool ONDXKey::operator < (const ONDXKey
& rKey
) const
285 return Compare(rKey
) < 0;
287 inline bool ONDXKey::operator > (const ONDXKey
& rKey
) const
289 return Compare(rKey
) > 0;
291 inline bool ONDXKey::operator <= (const ONDXKey
& rKey
) const
293 return !operator > (rKey
);
296 inline void ONDXNode::SetChild(const ONDXPagePtr
& rCh
, ONDXPage
* pParent
)
300 aChild
->SetParent(pParent
);
307 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */