xref: /aoo42x/main/store/source/stortree.hxx (revision b9fd132d)
11a5fa39bSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
31a5fa39bSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
41a5fa39bSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
51a5fa39bSAndrew Rist  * distributed with this work for additional information
61a5fa39bSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
71a5fa39bSAndrew Rist  * to you under the Apache License, Version 2.0 (the
81a5fa39bSAndrew Rist  * "License"); you may not use this file except in compliance
91a5fa39bSAndrew Rist  * with the License.  You may obtain a copy of the License at
101a5fa39bSAndrew Rist  *
111a5fa39bSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
121a5fa39bSAndrew Rist  *
131a5fa39bSAndrew Rist  * Unless required by applicable law or agreed to in writing,
141a5fa39bSAndrew Rist  * software distributed under the License is distributed on an
151a5fa39bSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
161a5fa39bSAndrew Rist  * KIND, either express or implied.  See the License for the
171a5fa39bSAndrew Rist  * specific language governing permissions and limitations
181a5fa39bSAndrew Rist  * under the License.
191a5fa39bSAndrew Rist  *
201a5fa39bSAndrew Rist  *************************************************************/
211a5fa39bSAndrew Rist 
221a5fa39bSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef _STORE_STORTREE_HXX
25*b9fd132dSpfg #define _STORE_STORTREE_HXX "$Revision$"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "sal/types.h"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "store/types.h"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "storbase.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace store
34cdf0e10cSrcweir {
35cdf0e10cSrcweir 
36cdf0e10cSrcweir class OStorePageBIOS;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir /*========================================================================
39cdf0e10cSrcweir  *
40cdf0e10cSrcweir  * OStoreBTreeEntry.
41cdf0e10cSrcweir  *
42cdf0e10cSrcweir  *======================================================================*/
43cdf0e10cSrcweir struct OStoreBTreeEntry
44cdf0e10cSrcweir {
45cdf0e10cSrcweir 	typedef OStorePageKey  K;
46cdf0e10cSrcweir 	typedef OStorePageLink L;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 	/** Representation.
49cdf0e10cSrcweir 	*/
50cdf0e10cSrcweir 	K          m_aKey;
51cdf0e10cSrcweir 	L          m_aLink;
52cdf0e10cSrcweir 	sal_uInt32 m_nAttrib;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 	/** Construction.
55cdf0e10cSrcweir 	*/
OStoreBTreeEntrystore::OStoreBTreeEntry56cdf0e10cSrcweir 	explicit OStoreBTreeEntry (
57cdf0e10cSrcweir         K const &  rKey    = K(),
58cdf0e10cSrcweir         L const &  rLink   = L(),
59cdf0e10cSrcweir         sal_uInt32 nAttrib = 0)
60cdf0e10cSrcweir         : m_aKey    (rKey),
61cdf0e10cSrcweir           m_aLink   (rLink),
62cdf0e10cSrcweir           m_nAttrib (store::htonl(nAttrib))
63cdf0e10cSrcweir 	{}
64cdf0e10cSrcweir 
OStoreBTreeEntrystore::OStoreBTreeEntry65cdf0e10cSrcweir 	OStoreBTreeEntry (const OStoreBTreeEntry & rhs)
66cdf0e10cSrcweir 		: m_aKey    (rhs.m_aKey),
67cdf0e10cSrcweir 		  m_aLink   (rhs.m_aLink),
68cdf0e10cSrcweir 		  m_nAttrib (rhs.m_nAttrib)
69cdf0e10cSrcweir 	{}
70cdf0e10cSrcweir 
operator =store::OStoreBTreeEntry71cdf0e10cSrcweir 	OStoreBTreeEntry& operator= (const OStoreBTreeEntry & rhs)
72cdf0e10cSrcweir 	{
73cdf0e10cSrcweir 		m_aKey    = rhs.m_aKey;
74cdf0e10cSrcweir 		m_aLink   = rhs.m_aLink;
75cdf0e10cSrcweir 		m_nAttrib = rhs.m_nAttrib;
76cdf0e10cSrcweir 		return *this;
77cdf0e10cSrcweir 	}
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	/** Comparison.
80cdf0e10cSrcweir 	*/
81cdf0e10cSrcweir 	enum CompareResult
82cdf0e10cSrcweir 	{
83cdf0e10cSrcweir 		COMPARE_LESS    = -1,
84cdf0e10cSrcweir 		COMPARE_EQUAL   =  0,
85cdf0e10cSrcweir 		COMPARE_GREATER =  1
86cdf0e10cSrcweir 	};
87cdf0e10cSrcweir 
comparestore::OStoreBTreeEntry88cdf0e10cSrcweir 	CompareResult compare (const OStoreBTreeEntry& rOther) const
89cdf0e10cSrcweir 	{
90cdf0e10cSrcweir 		if (m_aKey < rOther.m_aKey)
91cdf0e10cSrcweir 			return COMPARE_LESS;
92cdf0e10cSrcweir 		else if (m_aKey == rOther.m_aKey)
93cdf0e10cSrcweir 			return COMPARE_EQUAL;
94cdf0e10cSrcweir 		else
95cdf0e10cSrcweir 			return COMPARE_GREATER;
96cdf0e10cSrcweir 	}
97cdf0e10cSrcweir };
98cdf0e10cSrcweir 
99cdf0e10cSrcweir /*========================================================================
100cdf0e10cSrcweir  *
101cdf0e10cSrcweir  * OStoreBTreeNodeData.
102cdf0e10cSrcweir  *
103cdf0e10cSrcweir  *======================================================================*/
104cdf0e10cSrcweir #define STORE_MAGIC_BTREENODE sal_uInt32(0x58190322)
105cdf0e10cSrcweir 
106cdf0e10cSrcweir struct OStoreBTreeNodeData : public store::OStorePageData
107cdf0e10cSrcweir {
108cdf0e10cSrcweir 	typedef OStorePageData      base;
109cdf0e10cSrcweir 	typedef OStoreBTreeNodeData self;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 	typedef OStorePageGuard     G;
112cdf0e10cSrcweir 	typedef OStoreBTreeEntry    T;
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	/** Representation.
115cdf0e10cSrcweir      */
116cdf0e10cSrcweir 	G m_aGuard;
117cdf0e10cSrcweir 	T m_pData[1];
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /** type.
120cdf0e10cSrcweir      */
121cdf0e10cSrcweir     static const sal_uInt32 theTypeId = STORE_MAGIC_BTREENODE;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 	/** theSize.
124cdf0e10cSrcweir      */
125cdf0e10cSrcweir     static const size_t     theSize     = sizeof(G);
126cdf0e10cSrcweir     static const sal_uInt16 thePageSize = base::theSize + self::theSize;
127cdf0e10cSrcweir     STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize);
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 	/** capacity.
130cdf0e10cSrcweir 	*/
capacitystore::OStoreBTreeNodeData131cdf0e10cSrcweir 	sal_uInt16 capacity (void) const
132cdf0e10cSrcweir 	{
133cdf0e10cSrcweir 		return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize);
134cdf0e10cSrcweir 	}
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	/** capacityCount (must be even).
137cdf0e10cSrcweir 	*/
capacityCountstore::OStoreBTreeNodeData138cdf0e10cSrcweir 	sal_uInt16 capacityCount (void) const
139cdf0e10cSrcweir 	{
140cdf0e10cSrcweir 		return sal_uInt16(capacity() / sizeof(T));
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	/** usage.
144cdf0e10cSrcweir 	*/
usagestore::OStoreBTreeNodeData145cdf0e10cSrcweir 	sal_uInt16 usage (void) const
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir 		return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize);
148cdf0e10cSrcweir 	}
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 	/** usageCount.
151cdf0e10cSrcweir 	*/
usageCountstore::OStoreBTreeNodeData152cdf0e10cSrcweir 	sal_uInt16 usageCount (void) const
153cdf0e10cSrcweir 	{
154cdf0e10cSrcweir 		return sal_uInt16(usage() / sizeof(T));
155cdf0e10cSrcweir 	}
usageCountstore::OStoreBTreeNodeData156cdf0e10cSrcweir 	void usageCount (sal_uInt16 nCount)
157cdf0e10cSrcweir 	{
158cdf0e10cSrcweir         size_t const nBytes = self::thePageSize + nCount * sizeof(T);
159cdf0e10cSrcweir 		base::m_aDescr.m_nUsed = store::htons(sal::static_int_cast< sal_uInt16 >(nBytes));
160cdf0e10cSrcweir 	}
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 	/** Construction.
163cdf0e10cSrcweir 	*/
164cdf0e10cSrcweir 	explicit OStoreBTreeNodeData (sal_uInt16 nPageSize = self::thePageSize);
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 	/** guard (external representation).
167cdf0e10cSrcweir 	*/
guardstore::OStoreBTreeNodeData168cdf0e10cSrcweir 	void guard()
169cdf0e10cSrcweir 	{
170cdf0e10cSrcweir 		sal_uInt32 nCRC32 = 0;
171cdf0e10cSrcweir 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
172cdf0e10cSrcweir 		nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
173cdf0e10cSrcweir 		m_aGuard.m_nCRC32 = store::htonl(nCRC32);
174cdf0e10cSrcweir 	}
175cdf0e10cSrcweir 
176cdf0e10cSrcweir 	/** verify (external representation).
177cdf0e10cSrcweir 	*/
verifystore::OStoreBTreeNodeData178cdf0e10cSrcweir 	storeError verify() const
179cdf0e10cSrcweir 	{
180cdf0e10cSrcweir 		sal_uInt32 nCRC32 = 0;
181cdf0e10cSrcweir 		nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
182cdf0e10cSrcweir 		nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity());
183cdf0e10cSrcweir 		if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
184cdf0e10cSrcweir 			return store_E_InvalidChecksum;
185cdf0e10cSrcweir 		else
186cdf0e10cSrcweir 			return store_E_None;
187cdf0e10cSrcweir 	}
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 	/** depth.
190cdf0e10cSrcweir 	*/
depthstore::OStoreBTreeNodeData191cdf0e10cSrcweir 	sal_uInt32 depth (void) const
192cdf0e10cSrcweir 	{
193cdf0e10cSrcweir 		return store::ntohl(self::m_aGuard.m_nMagic);
194cdf0e10cSrcweir 	}
depthstore::OStoreBTreeNodeData195cdf0e10cSrcweir 	void depth (sal_uInt32 nDepth)
196cdf0e10cSrcweir 	{
197cdf0e10cSrcweir 		self::m_aGuard.m_nMagic = store::htonl(nDepth);
198cdf0e10cSrcweir 	}
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 	/** queryMerge.
201cdf0e10cSrcweir 	*/
queryMergestore::OStoreBTreeNodeData202cdf0e10cSrcweir 	sal_Bool queryMerge (const self &rPageR) const
203cdf0e10cSrcweir 	{
204cdf0e10cSrcweir 		return ((usageCount() + rPageR.usageCount()) <= capacityCount());
205cdf0e10cSrcweir 	}
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 	/** querySplit.
208cdf0e10cSrcweir 	*/
querySplitstore::OStoreBTreeNodeData209cdf0e10cSrcweir 	sal_Bool querySplit (void) const
210cdf0e10cSrcweir 	{
211cdf0e10cSrcweir 		return (!(usageCount() < capacityCount()));
212cdf0e10cSrcweir 	}
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 	/** Operation.
215cdf0e10cSrcweir 	*/
216cdf0e10cSrcweir 	sal_uInt16 find   (const T& t) const;
217cdf0e10cSrcweir 	void       insert (sal_uInt16 i, const T& t);
218cdf0e10cSrcweir 	void       remove (sal_uInt16 i);
219cdf0e10cSrcweir 
220cdf0e10cSrcweir #if 0  /* NYI */
221cdf0e10cSrcweir 	/** merge (with right page).
222cdf0e10cSrcweir 	 */
223cdf0e10cSrcweir 	void merge (const self& rPageR);
224cdf0e10cSrcweir #endif
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	/** split (left half copied from right half of left page).
227cdf0e10cSrcweir 	*/
228cdf0e10cSrcweir 	void split (const self& rPageL);
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	/** truncate (to n elements).
231cdf0e10cSrcweir 	*/
232cdf0e10cSrcweir 	void truncate (sal_uInt16 n);
233cdf0e10cSrcweir };
234cdf0e10cSrcweir 
235cdf0e10cSrcweir /*========================================================================
236cdf0e10cSrcweir  *
237cdf0e10cSrcweir  * OStoreBTreeNodeObject.
238cdf0e10cSrcweir  *
239cdf0e10cSrcweir  *======================================================================*/
240cdf0e10cSrcweir class OStoreBTreeNodeObject : public store::OStorePageObject
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	typedef OStorePageObject      base;
243cdf0e10cSrcweir 	typedef OStoreBTreeNodeObject self;
244cdf0e10cSrcweir 	typedef OStoreBTreeNodeData   page;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	typedef OStoreBTreeEntry      T;
247cdf0e10cSrcweir 
248cdf0e10cSrcweir public:
249cdf0e10cSrcweir 	/** Construction.
250cdf0e10cSrcweir 	*/
OStoreBTreeNodeObject(PageHolder const & rxPage=PageHolder ())251cdf0e10cSrcweir     explicit OStoreBTreeNodeObject (PageHolder const & rxPage = PageHolder())
252cdf0e10cSrcweir         : OStorePageObject (rxPage)
253cdf0e10cSrcweir     {}
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	/** External representation.
256cdf0e10cSrcweir 	*/
257cdf0e10cSrcweir 	virtual storeError guard  (sal_uInt32 nAddr);
258cdf0e10cSrcweir 	virtual storeError verify (sal_uInt32 nAddr) const;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 	/** split.
261cdf0e10cSrcweir      *
262cdf0e10cSrcweir      *  @param rxPageL [inout] left child to be split
263cdf0e10cSrcweir      */
264cdf0e10cSrcweir 	storeError split (
265cdf0e10cSrcweir 		sal_uInt16                 nIndexL,
266cdf0e10cSrcweir 		PageHolderObject< page > & rxPageL,
267cdf0e10cSrcweir 		OStorePageBIOS &           rBIOS);
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 	/** remove (down to leaf node, recursive).
270cdf0e10cSrcweir 	*/
271cdf0e10cSrcweir 	storeError remove (
272cdf0e10cSrcweir 		sal_uInt16         nIndexL,
273cdf0e10cSrcweir 		OStoreBTreeEntry & rEntryL,
274cdf0e10cSrcweir 		OStorePageBIOS &   rBIOS);
275cdf0e10cSrcweir };
276cdf0e10cSrcweir 
277cdf0e10cSrcweir /*========================================================================
278cdf0e10cSrcweir  *
279cdf0e10cSrcweir  * OStoreBTreeRootObject.
280cdf0e10cSrcweir  *
281cdf0e10cSrcweir  *======================================================================*/
282cdf0e10cSrcweir class OStoreBTreeRootObject : public store::OStoreBTreeNodeObject
283cdf0e10cSrcweir {
284cdf0e10cSrcweir 	typedef OStoreBTreeNodeObject base;
285cdf0e10cSrcweir 	typedef OStoreBTreeNodeData   page;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	typedef OStoreBTreeEntry      T;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir public:
290cdf0e10cSrcweir 	/** Construction.
291cdf0e10cSrcweir      */
OStoreBTreeRootObject(PageHolder const & rxPage=PageHolder ())292cdf0e10cSrcweir     explicit OStoreBTreeRootObject (PageHolder const & rxPage = PageHolder())
293cdf0e10cSrcweir         : OStoreBTreeNodeObject (rxPage)
294cdf0e10cSrcweir     {}
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     storeError loadOrCreate (
297cdf0e10cSrcweir         sal_uInt32       nAddr,
298cdf0e10cSrcweir         OStorePageBIOS & rBIOS);
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     /** find_lookup (w/o split()).
301cdf0e10cSrcweir      *  Precond: root node page loaded.
302cdf0e10cSrcweir      */
303cdf0e10cSrcweir     storeError find_lookup (
304cdf0e10cSrcweir         OStoreBTreeNodeObject & rNode,  // [out]
305cdf0e10cSrcweir         sal_uInt16 &            rIndex, // [out]
306cdf0e10cSrcweir         OStorePageKey const &   rKey,
307cdf0e10cSrcweir         OStorePageBIOS &        rBIOS);
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     /** find_insert (possibly with split()).
310cdf0e10cSrcweir      *  Precond: root node page loaded.
311cdf0e10cSrcweir      */
312cdf0e10cSrcweir     storeError find_insert (
313cdf0e10cSrcweir         OStoreBTreeNodeObject & rNode,
314cdf0e10cSrcweir         sal_uInt16 &            rIndex,
315cdf0e10cSrcweir         OStorePageKey const &   rKey,
316cdf0e10cSrcweir         OStorePageBIOS &        rBIOS);
317cdf0e10cSrcweir 
318cdf0e10cSrcweir private:
319cdf0e10cSrcweir     /** testInvariant.
320cdf0e10cSrcweir      *  Precond: root node page loaded.
321cdf0e10cSrcweir      */
322cdf0e10cSrcweir     bool testInvariant (char const * message);
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 	/** change (Root).
325cdf0e10cSrcweir      *
326cdf0e10cSrcweir      *  @param rxPageL [out] prev. root (needs split)
327cdf0e10cSrcweir      */
328cdf0e10cSrcweir 	storeError change (
329cdf0e10cSrcweir 		PageHolderObject< page > & rxPageL,
330cdf0e10cSrcweir 		OStorePageBIOS &           rBIOS);
331cdf0e10cSrcweir };
332cdf0e10cSrcweir 
333cdf0e10cSrcweir /*========================================================================
334cdf0e10cSrcweir  *
335cdf0e10cSrcweir  * The End.
336cdf0e10cSrcweir  *
337cdf0e10cSrcweir  *======================================================================*/
338cdf0e10cSrcweir 
339cdf0e10cSrcweir } // namespace store
340cdf0e10cSrcweir 
341cdf0e10cSrcweir #endif /* !_STORE_STORTREE_HXX */
342