Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / store / source / stortree.hxx
blob15cb581d1e01db8192c3991b5b2d63be899c7cfc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #ifndef _STORE_STORTREE_HXX
30 #define _STORE_STORTREE_HXX
32 #include "sal/types.h"
34 #include "store/types.h"
36 #include "storbase.hxx"
38 namespace store
41 class OStorePageBIOS;
43 /*========================================================================
45 * OStoreBTreeEntry.
47 *======================================================================*/
48 struct OStoreBTreeEntry
50 typedef OStorePageKey K;
51 typedef OStorePageLink L;
53 /** Representation.
55 K m_aKey;
56 L m_aLink;
57 sal_uInt32 m_nAttrib;
59 /** Construction.
61 explicit OStoreBTreeEntry (
62 K const & rKey = K(),
63 L const & rLink = L(),
64 sal_uInt32 nAttrib = 0)
65 : m_aKey (rKey),
66 m_aLink (rLink),
67 m_nAttrib (store::htonl(nAttrib))
70 OStoreBTreeEntry (const OStoreBTreeEntry & rhs)
71 : m_aKey (rhs.m_aKey),
72 m_aLink (rhs.m_aLink),
73 m_nAttrib (rhs.m_nAttrib)
76 OStoreBTreeEntry& operator= (const OStoreBTreeEntry & rhs)
78 m_aKey = rhs.m_aKey;
79 m_aLink = rhs.m_aLink;
80 m_nAttrib = rhs.m_nAttrib;
81 return *this;
84 /** Comparison.
86 enum CompareResult
88 COMPARE_LESS = -1,
89 COMPARE_EQUAL = 0,
90 COMPARE_GREATER = 1
93 CompareResult compare (const OStoreBTreeEntry& rOther) const
95 if (m_aKey < rOther.m_aKey)
96 return COMPARE_LESS;
97 else if (m_aKey == rOther.m_aKey)
98 return COMPARE_EQUAL;
99 else
100 return COMPARE_GREATER;
104 /*========================================================================
106 * OStoreBTreeNodeData.
108 *======================================================================*/
109 #define STORE_MAGIC_BTREENODE sal_uInt32(0x58190322)
111 struct OStoreBTreeNodeData : public store::OStorePageData
113 typedef OStorePageData base;
114 typedef OStoreBTreeNodeData self;
116 typedef OStorePageGuard G;
117 typedef OStoreBTreeEntry T;
119 /** Representation.
121 G m_aGuard;
122 T m_pData[1];
124 /** type.
126 static const sal_uInt32 theTypeId = STORE_MAGIC_BTREENODE;
128 /** theSize.
130 static const size_t theSize = sizeof(G);
131 static const sal_uInt16 thePageSize = base::theSize + self::theSize;
132 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
134 /** capacity.
136 sal_uInt16 capacity (void) const
138 return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize);
141 /** capacityCount (must be even).
143 sal_uInt16 capacityCount (void) const
145 return sal_uInt16(capacity() / sizeof(T));
148 /** usage.
150 sal_uInt16 usage (void) const
152 return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize);
155 /** usageCount.
157 sal_uInt16 usageCount (void) const
159 return sal_uInt16(usage() / sizeof(T));
161 void usageCount (sal_uInt16 nCount)
163 size_t const nBytes = self::thePageSize + nCount * sizeof(T);
164 base::m_aDescr.m_nUsed = store::htons(sal::static_int_cast< sal_uInt16 >(nBytes));
167 /** Construction.
169 explicit OStoreBTreeNodeData (sal_uInt16 nPageSize = self::thePageSize);
171 /** guard (external representation).
173 void guard()
175 sal_uInt32 nCRC32 = 0;
176 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
177 nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
178 m_aGuard.m_nCRC32 = store::htonl(nCRC32);
181 /** verify (external representation).
183 storeError verify() const
185 sal_uInt32 nCRC32 = 0;
186 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
187 nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
188 if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
189 return store_E_InvalidChecksum;
190 else
191 return store_E_None;
194 /** depth.
196 sal_uInt32 depth (void) const
198 return store::ntohl(self::m_aGuard.m_nMagic);
200 void depth (sal_uInt32 nDepth)
202 self::m_aGuard.m_nMagic = store::htonl(nDepth);
205 /** queryMerge.
207 sal_Bool queryMerge (const self &rPageR) const
209 return ((usageCount() + rPageR.usageCount()) <= capacityCount());
212 /** querySplit.
214 sal_Bool querySplit (void) const
216 return (!(usageCount() < capacityCount()));
219 /** Operation.
221 sal_uInt16 find (const T& t) const;
222 void insert (sal_uInt16 i, const T& t);
223 void remove (sal_uInt16 i);
225 /** split (left half copied from right half of left page).
227 void split (const self& rPageL);
229 /** truncate (to n elements).
231 void truncate (sal_uInt16 n);
234 /*========================================================================
236 * OStoreBTreeNodeObject.
238 *======================================================================*/
239 class OStoreBTreeNodeObject : public store::OStorePageObject
241 typedef OStorePageObject base;
242 typedef OStoreBTreeNodeObject self;
243 typedef OStoreBTreeNodeData page;
245 typedef OStoreBTreeEntry T;
247 public:
248 /** Construction.
250 explicit OStoreBTreeNodeObject (PageHolder const & rxPage = PageHolder())
251 : OStorePageObject (rxPage)
254 /** External representation.
256 virtual storeError guard (sal_uInt32 nAddr);
257 virtual storeError verify (sal_uInt32 nAddr) const;
259 /** split.
261 * @param rxPageL [inout] left child to be split
263 storeError split (
264 sal_uInt16 nIndexL,
265 PageHolderObject< page > & rxPageL,
266 OStorePageBIOS & rBIOS);
268 /** remove (down to leaf node, recursive).
270 storeError remove (
271 sal_uInt16 nIndexL,
272 OStoreBTreeEntry & rEntryL,
273 OStorePageBIOS & rBIOS);
276 /*========================================================================
278 * OStoreBTreeRootObject.
280 *======================================================================*/
281 class OStoreBTreeRootObject : public store::OStoreBTreeNodeObject
283 typedef OStoreBTreeNodeObject base;
284 typedef OStoreBTreeNodeData page;
286 typedef OStoreBTreeEntry T;
288 public:
289 /** Construction.
291 explicit OStoreBTreeRootObject (PageHolder const & rxPage = PageHolder())
292 : OStoreBTreeNodeObject (rxPage)
295 storeError loadOrCreate (
296 sal_uInt32 nAddr,
297 OStorePageBIOS & rBIOS);
299 /** find_lookup (w/o split()).
300 * Precond: root node page loaded.
302 storeError find_lookup (
303 OStoreBTreeNodeObject & rNode, // [out]
304 sal_uInt16 & rIndex, // [out]
305 OStorePageKey const & rKey,
306 OStorePageBIOS & rBIOS);
308 /** find_insert (possibly with split()).
309 * Precond: root node page loaded.
311 storeError find_insert (
312 OStoreBTreeNodeObject & rNode,
313 sal_uInt16 & rIndex,
314 OStorePageKey const & rKey,
315 OStorePageBIOS & rBIOS);
317 private:
318 /** testInvariant.
319 * Precond: root node page loaded.
321 bool testInvariant (char const * message);
323 /** change (Root).
325 * @param rxPageL [out] prev. root (needs split)
327 storeError change (
328 PageHolderObject< page > & rxPageL,
329 OStorePageBIOS & rBIOS);
332 /*========================================================================
334 * The End.
336 *======================================================================*/
338 } // namespace store
340 #endif /* !_STORE_STORTREE_HXX */
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */