Branch libreoffice-5-0-4
[LibreOffice.git] / store / source / stortree.hxx
blob2cfe8f2ee683098ed4358bcaa2e12020c5d6b2dd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #ifndef INCLUDED_STORE_SOURCE_STORTREE_HXX
21 #define INCLUDED_STORE_SOURCE_STORTREE_HXX
23 #include "sal/config.h"
25 #include "sal/types.h"
27 #include "store/types.h"
29 #include "storbase.hxx"
31 namespace store
34 class OStorePageBIOS;
36 /*========================================================================
38 * OStoreBTreeEntry.
40 *======================================================================*/
41 struct OStoreBTreeEntry
43 typedef OStorePageKey K;
44 typedef OStorePageLink L;
46 /** Representation.
48 K m_aKey;
49 L m_aLink;
50 sal_uInt32 m_nAttrib;
52 /** Construction.
54 explicit OStoreBTreeEntry (
55 K const & rKey = K(),
56 L const & rLink = L(),
57 sal_uInt32 nAttrib = 0)
58 : m_aKey (rKey),
59 m_aLink (rLink),
60 m_nAttrib (store::htonl(nAttrib))
63 OStoreBTreeEntry (const OStoreBTreeEntry & rhs)
64 : m_aKey (rhs.m_aKey),
65 m_aLink (rhs.m_aLink),
66 m_nAttrib (rhs.m_nAttrib)
69 OStoreBTreeEntry& operator= (const OStoreBTreeEntry & rhs)
71 m_aKey = rhs.m_aKey;
72 m_aLink = rhs.m_aLink;
73 m_nAttrib = rhs.m_nAttrib;
74 return *this;
77 /** Comparison.
79 enum CompareResult
81 COMPARE_LESS = -1,
82 COMPARE_EQUAL = 0,
83 COMPARE_GREATER = 1
86 CompareResult compare (const OStoreBTreeEntry& rOther) const
88 if (m_aKey < rOther.m_aKey)
89 return COMPARE_LESS;
90 else if (m_aKey == rOther.m_aKey)
91 return COMPARE_EQUAL;
92 else
93 return COMPARE_GREATER;
97 /*========================================================================
99 * OStoreBTreeNodeData.
101 *======================================================================*/
102 #define STORE_MAGIC_BTREENODE sal_uInt32(0x58190322)
104 struct OStoreBTreeNodeData : public store::OStorePageData
106 typedef OStorePageData base;
107 typedef OStoreBTreeNodeData self;
109 typedef OStorePageGuard G;
110 typedef OStoreBTreeEntry T;
112 /** Representation.
114 G m_aGuard;
115 T m_pData[1];
117 /** type.
119 static const sal_uInt32 theTypeId = STORE_MAGIC_BTREENODE;
121 /** theSize.
123 static const size_t theSize = sizeof(G);
124 static const sal_uInt16 thePageSize = base::theSize + self::theSize;
125 static_assert(STORE_MINIMUM_PAGESIZE >= self::thePageSize, "got to be at least equal in size");
127 /** capacity.
129 sal_uInt16 capacity() const
131 return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize);
134 /** capacityCount (must be even).
136 sal_uInt16 capacityCount() const
138 return sal_uInt16(capacity() / sizeof(T));
141 /** usage.
143 sal_uInt16 usage() const
145 return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize);
148 /** usageCount.
150 sal_uInt16 usageCount() const
152 return sal_uInt16(usage() / sizeof(T));
154 void usageCount (sal_uInt16 nCount)
156 size_t const nBytes = self::thePageSize + nCount * sizeof(T);
157 base::m_aDescr.m_nUsed = store::htons(sal::static_int_cast< sal_uInt16 >(nBytes));
160 /** Construction.
162 explicit OStoreBTreeNodeData (sal_uInt16 nPageSize = self::thePageSize);
164 /** guard (external representation).
166 void guard()
168 sal_uInt32 nCRC32 = 0;
169 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
170 nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
171 m_aGuard.m_nCRC32 = store::htonl(nCRC32);
174 /** verify (external representation).
176 storeError verify() const
178 sal_uInt32 nCRC32 = 0;
179 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
180 nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
181 if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
182 return store_E_InvalidChecksum;
183 else
184 return store_E_None;
187 /** depth.
189 sal_uInt32 depth() const
191 return store::ntohl(self::m_aGuard.m_nMagic);
193 void depth (sal_uInt32 nDepth)
195 self::m_aGuard.m_nMagic = store::htonl(nDepth);
198 /** queryMerge.
200 bool queryMerge (const self &rPageR) const
202 return ((usageCount() + rPageR.usageCount()) <= capacityCount());
205 /** querySplit.
207 bool querySplit() const
209 return (!(usageCount() < capacityCount()));
212 /** Operation.
214 sal_uInt16 find (const T& t) const;
215 void insert (sal_uInt16 i, const T& t);
216 void remove (sal_uInt16 i);
218 /** split (left half copied from right half of left page).
220 void split (const self& rPageL);
222 /** truncate (to n elements).
224 void truncate (sal_uInt16 n);
227 /*========================================================================
229 * OStoreBTreeNodeObject.
231 *======================================================================*/
232 class OStoreBTreeNodeObject : public store::OStorePageObject
234 typedef OStorePageObject base;
235 typedef OStoreBTreeNodeObject self;
236 typedef OStoreBTreeNodeData page;
238 typedef OStoreBTreeEntry T;
240 public:
241 /** Construction.
243 explicit OStoreBTreeNodeObject (PageHolder const & rxPage = PageHolder())
244 : OStorePageObject (rxPage)
247 /** External representation.
249 virtual storeError guard (sal_uInt32 nAddr) SAL_OVERRIDE;
250 virtual storeError verify (sal_uInt32 nAddr) const SAL_OVERRIDE;
252 /** split.
254 * @param rxPageL [inout] left child to be split
256 storeError split (
257 sal_uInt16 nIndexL,
258 PageHolderObject< page > & rxPageL,
259 OStorePageBIOS & rBIOS);
261 /** remove (down to leaf node, recursive).
263 storeError remove (
264 sal_uInt16 nIndexL,
265 OStoreBTreeEntry & rEntryL,
266 OStorePageBIOS & rBIOS);
269 /*========================================================================
271 * OStoreBTreeRootObject.
273 *======================================================================*/
274 class OStoreBTreeRootObject : public store::OStoreBTreeNodeObject
276 typedef OStoreBTreeNodeObject base;
277 typedef OStoreBTreeNodeData page;
279 typedef OStoreBTreeEntry T;
281 public:
282 /** Construction.
284 explicit OStoreBTreeRootObject (PageHolder const & rxPage = PageHolder())
285 : OStoreBTreeNodeObject (rxPage)
288 storeError loadOrCreate (
289 sal_uInt32 nAddr,
290 OStorePageBIOS & rBIOS);
292 /** find_lookup (w/o split()).
293 * Precond: root node page loaded.
295 storeError find_lookup (
296 OStoreBTreeNodeObject & rNode, // [out]
297 sal_uInt16 & rIndex, // [out]
298 OStorePageKey const & rKey,
299 OStorePageBIOS & rBIOS);
301 /** find_insert (possibly with split()).
302 * Precond: root node page loaded.
304 storeError find_insert (
305 OStoreBTreeNodeObject & rNode,
306 sal_uInt16 & rIndex,
307 OStorePageKey const & rKey,
308 OStorePageBIOS & rBIOS);
310 private:
311 /** testInvariant.
312 * Precond: root node page loaded.
314 void testInvariant (char const * message);
316 /** change (Root).
318 * @param rxPageL [out] prev. root (needs split)
320 storeError change (
321 PageHolderObject< page > & rxPageL,
322 OStorePageBIOS & rBIOS);
325 /*========================================================================
327 * The End.
329 *======================================================================*/
331 } // namespace store
333 #endif // INCLUDED_STORE_SOURCE_STORTREE_HXX
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */