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"
43 /*========================================================================
47 *======================================================================*/
48 struct OStoreBTreeEntry
50 typedef OStorePageKey K
;
51 typedef OStorePageLink L
;
61 explicit OStoreBTreeEntry (
63 L
const & rLink
= L(),
64 sal_uInt32 nAttrib
= 0)
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
)
79 m_aLink
= rhs
.m_aLink
;
80 m_nAttrib
= rhs
.m_nAttrib
;
93 CompareResult
compare (const OStoreBTreeEntry
& rOther
) const
95 if (m_aKey
< rOther
.m_aKey
)
97 else if (m_aKey
== rOther
.m_aKey
)
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
;
126 static const sal_uInt32 theTypeId
= STORE_MAGIC_BTREENODE
;
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
);
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
));
150 sal_uInt16
usage (void) const
152 return (store::ntohs(base::m_aDescr
.m_nUsed
) - self::thePageSize
);
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
));
169 explicit OStoreBTreeNodeData (sal_uInt16 nPageSize
= self::thePageSize
);
171 /** guard (external representation).
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
;
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
);
207 sal_Bool
queryMerge (const self
&rPageR
) const
209 return ((usageCount() + rPageR
.usageCount()) <= capacityCount());
214 sal_Bool
querySplit (void) const
216 return (!(usageCount() < capacityCount()));
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
;
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;
261 * @param rxPageL [inout] left child to be split
265 PageHolderObject
< page
> & rxPageL
,
266 OStorePageBIOS
& rBIOS
);
268 /** remove (down to leaf node, recursive).
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
;
291 explicit OStoreBTreeRootObject (PageHolder
const & rxPage
= PageHolder())
292 : OStoreBTreeNodeObject (rxPage
)
295 storeError
loadOrCreate (
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
,
314 OStorePageKey
const & rKey
,
315 OStorePageBIOS
& rBIOS
);
319 * Precond: root node page loaded.
321 bool testInvariant (char const * message
);
325 * @param rxPageL [out] prev. root (needs split)
328 PageHolderObject
< page
> & rxPageL
,
329 OStorePageBIOS
& rBIOS
);
332 /*========================================================================
336 *======================================================================*/
340 #endif /* !_STORE_STORTREE_HXX */
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */