1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: stortree.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef _STORE_STORTREE_HXX
32 #define _STORE_STORTREE_HXX "$Revision: 1.6.8.2 $"
34 #include "sal/types.h"
36 #include "store/types.h"
38 #include "storbase.hxx"
45 /*========================================================================
49 *======================================================================*/
50 struct OStoreBTreeEntry
52 typedef OStorePageKey K
;
53 typedef OStorePageLink L
;
63 explicit OStoreBTreeEntry (
65 L
const & rLink
= L(),
66 sal_uInt32 nAttrib
= 0)
69 m_nAttrib (store::htonl(nAttrib
))
72 OStoreBTreeEntry (const OStoreBTreeEntry
& rhs
)
73 : m_aKey (rhs
.m_aKey
),
74 m_aLink (rhs
.m_aLink
),
75 m_nAttrib (rhs
.m_nAttrib
)
78 OStoreBTreeEntry
& operator= (const OStoreBTreeEntry
& rhs
)
81 m_aLink
= rhs
.m_aLink
;
82 m_nAttrib
= rhs
.m_nAttrib
;
95 CompareResult
compare (const OStoreBTreeEntry
& rOther
) const
97 if (m_aKey
< rOther
.m_aKey
)
99 else if (m_aKey
== rOther
.m_aKey
)
100 return COMPARE_EQUAL
;
102 return COMPARE_GREATER
;
106 /*========================================================================
108 * OStoreBTreeNodeData.
110 *======================================================================*/
111 #define STORE_MAGIC_BTREENODE sal_uInt32(0x58190322)
113 struct OStoreBTreeNodeData
: public store::OStorePageData
115 typedef OStorePageData base
;
116 typedef OStoreBTreeNodeData self
;
118 typedef OStorePageGuard G
;
119 typedef OStoreBTreeEntry T
;
128 static const sal_uInt32 theTypeId
= STORE_MAGIC_BTREENODE
;
132 static const size_t theSize
= sizeof(G
);
133 static const sal_uInt16 thePageSize
= base::theSize
+ self::theSize
;
134 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= self::thePageSize
);
138 sal_uInt16
capacity (void) const
140 return (store::ntohs(base::m_aDescr
.m_nSize
) - self::thePageSize
);
143 /** capacityCount (must be even).
145 sal_uInt16
capacityCount (void) const
147 return sal_uInt16(capacity() / sizeof(T
));
152 sal_uInt16
usage (void) const
154 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
159 sal_uInt16
usageCount (void) const
161 return sal_uInt16(usage() / sizeof(T
));
163 void usageCount (sal_uInt16 nCount
)
165 size_t const nBytes
= self::thePageSize
+ nCount
* sizeof(T
);
166 base::m_aDescr
.m_nUsed
= store::htons(sal::static_int_cast
< sal_uInt16
>(nBytes
));
171 explicit OStoreBTreeNodeData (sal_uInt16 nPageSize
= self::thePageSize
);
173 /** guard (external representation).
177 sal_uInt32 nCRC32
= 0;
178 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
179 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
180 m_aGuard
.m_nCRC32
= store::htonl(nCRC32
);
183 /** verify (external representation).
185 storeError
verify() const
187 sal_uInt32 nCRC32
= 0;
188 nCRC32
= rtl_crc32 (nCRC32
, &m_aGuard
.m_nMagic
, sizeof(sal_uInt32
));
189 nCRC32
= rtl_crc32 (nCRC32
, m_pData
, capacity());
190 if (m_aGuard
.m_nCRC32
!= store::htonl(nCRC32
))
191 return store_E_InvalidChecksum
;
198 sal_uInt32
depth (void) const
200 return store::ntohl(self::m_aGuard
.m_nMagic
);
202 void depth (sal_uInt32 nDepth
)
204 self::m_aGuard
.m_nMagic
= store::htonl(nDepth
);
209 sal_Bool
queryMerge (const self
&rPageR
) const
211 return ((usageCount() + rPageR
.usageCount()) <= capacityCount());
216 sal_Bool
querySplit (void) const
218 return (!(usageCount() < capacityCount()));
223 sal_uInt16
find (const T
& t
) const;
224 void insert (sal_uInt16 i
, const T
& t
);
225 void remove (sal_uInt16 i
);
228 /** merge (with right page).
230 void merge (const self
& rPageR
);
233 /** split (left half copied from right half of left page).
235 void split (const self
& rPageL
);
237 /** truncate (to n elements).
239 void truncate (sal_uInt16 n
);
242 /*========================================================================
244 * OStoreBTreeNodeObject.
246 *======================================================================*/
247 class OStoreBTreeNodeObject
: public store::OStorePageObject
249 typedef OStorePageObject base
;
250 typedef OStoreBTreeNodeObject self
;
251 typedef OStoreBTreeNodeData page
;
253 typedef OStoreBTreeEntry T
;
258 explicit OStoreBTreeNodeObject (PageHolder
const & rxPage
= PageHolder())
259 : OStorePageObject (rxPage
)
262 /** External representation.
264 virtual storeError
guard (sal_uInt32 nAddr
);
265 virtual storeError
verify (sal_uInt32 nAddr
) const;
269 * @param rxPageL [inout] left child to be split
273 PageHolderObject
< page
> & rxPageL
,
274 OStorePageBIOS
& rBIOS
);
276 /** remove (down to leaf node, recursive).
280 OStoreBTreeEntry
& rEntryL
,
281 OStorePageBIOS
& rBIOS
);
284 /*========================================================================
286 * OStoreBTreeRootObject.
288 *======================================================================*/
289 class OStoreBTreeRootObject
: public store::OStoreBTreeNodeObject
291 typedef OStoreBTreeNodeObject base
;
292 typedef OStoreBTreeNodeData page
;
294 typedef OStoreBTreeEntry T
;
299 explicit OStoreBTreeRootObject (PageHolder
const & rxPage
= PageHolder())
300 : OStoreBTreeNodeObject (rxPage
)
303 storeError
loadOrCreate (
305 OStorePageBIOS
& rBIOS
);
307 /** find_lookup (w/o split()).
308 * Precond: root node page loaded.
310 storeError
find_lookup (
311 OStoreBTreeNodeObject
& rNode
, // [out]
312 sal_uInt16
& rIndex
, // [out]
313 OStorePageKey
const & rKey
,
314 OStorePageBIOS
& rBIOS
);
316 /** find_insert (possibly with split()).
317 * Precond: root node page loaded.
319 storeError
find_insert (
320 OStoreBTreeNodeObject
& rNode
,
322 OStorePageKey
const & rKey
,
323 OStorePageBIOS
& rBIOS
);
327 * Precond: root node page loaded.
329 bool testInvariant (char const * message
);
333 * @param rxPageL [out] prev. root (needs split)
336 PageHolderObject
< page
> & rxPageL
,
337 OStorePageBIOS
& rBIOS
);
340 /*========================================================================
344 *======================================================================*/
348 #endif /* !_STORE_STORTREE_HXX */