LibreOffice Module store (master) 1
storbase.hxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#pragma once
21
22#include <sal/config.h>
24
25#include <sal/types.h>
26
27#include <rtl/crc.h>
28#include <rtl/ref.hxx>
29
30#include <osl/diagnose.h>
31#include <osl/endian.h>
32
33#include <store/types.h>
34
35#include <cstdlib>
36#include <memory>
37#include <utility>
38
42namespace store
43{
44
45#ifdef htons
46#undef htons
47#endif
48#ifdef ntohs
49#undef ntohs
50#endif
51
52#ifdef htonl
53#undef htonl
54#endif
55#ifdef ntohl
56#undef ntohl
57#endif
58
59#ifdef OSL_BIGENDIAN
60inline sal_uInt16 htons (sal_uInt16 h) { return OSL_SWAPWORD(h); }
61inline sal_uInt16 ntohs (sal_uInt16 n) { return OSL_SWAPWORD(n); }
62
63inline sal_uInt32 htonl (sal_uInt32 h) { return OSL_SWAPDWORD(h); }
64inline sal_uInt32 ntohl (sal_uInt32 n) { return OSL_SWAPDWORD(n); }
65#else
66inline sal_uInt16 htons (sal_uInt16 h) { return h; }
67inline sal_uInt16 ntohs (sal_uInt16 n) { return n; }
68
69inline sal_uInt32 htonl (sal_uInt32 h) { return h; }
70inline sal_uInt32 ntohl (sal_uInt32 n) { return n; }
71#endif /* OSL_BIGENDIAN */
72
74{
77 sal_uInt32 m_nMagic;
78 sal_uInt32 m_nCRC32;
79
82 explicit OStorePageGuard (sal_uInt32 nMagic = 0)
84 m_nCRC32 (store::htonl(0))
85 {}
86
87 void swap (OStorePageGuard & rhs)
88 {
89 std::swap(m_nMagic, rhs.m_nMagic);
90 std::swap(m_nCRC32, rhs.m_nCRC32);
91 }
92
94 : m_nMagic (rhs.m_nMagic),
95 m_nCRC32 (rhs.m_nCRC32)
96 {}
97
99 {
100 m_nMagic = rhs.m_nMagic;
101 m_nCRC32 = rhs.m_nCRC32;
102 return *this;
103 }
104
107 bool operator== (const OStorePageGuard& rhs) const
108 {
109 return ((m_nMagic == rhs.m_nMagic) &&
110 (m_nCRC32 == rhs.m_nCRC32) );
111 }
112};
113
114#define STORE_PAGE_NULL (sal_uInt32(~0))
115
117{
120 sal_uInt32 m_nAddr;
121 sal_uInt16 m_nSize;
122 sal_uInt16 m_nUsed;
123
127 sal_uInt32 nAddr,
128 sal_uInt16 nSize,
129 sal_uInt16 nUsed)
130 : m_nAddr (store::htonl(nAddr)),
131 m_nSize (store::htons(nSize)),
132 m_nUsed (store::htons(nUsed))
133 {}
134
136 {
137 std::swap(m_nAddr, rhs.m_nAddr);
138 std::swap(m_nSize, rhs.m_nSize);
139 std::swap(m_nUsed, rhs.m_nUsed);
140 }
141
143 : m_nAddr (rhs.m_nAddr),
144 m_nSize (rhs.m_nSize),
145 m_nUsed (rhs.m_nUsed)
146 {}
147
149 {
150 m_nAddr = rhs.m_nAddr;
151 m_nSize = rhs.m_nSize;
152 m_nUsed = rhs.m_nUsed;
153 return *this;
154 }
155
158 bool operator== (const OStorePageDescriptor & rhs) const
159 {
160 return ((m_nAddr == rhs.m_nAddr) &&
161 (m_nSize == rhs.m_nSize) );
162 }
163};
164
166{
169 sal_uInt32 m_nLow;
170 sal_uInt32 m_nHigh;
171
174 explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
175 : m_nLow (store::htonl(nLow)),
176 m_nHigh (store::htonl(nHigh))
177 {}
178
181 bool operator== (const OStorePageKey & rhs) const
182 {
183 return ((m_nLow == rhs.m_nLow ) &&
184 (m_nHigh == rhs.m_nHigh) );
185 }
186
187 bool operator< (const OStorePageKey & rhs) const
188 {
189 if (m_nHigh == rhs.m_nHigh)
190 return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow));
191 else
192 return (store::ntohl(m_nHigh) < store::ntohl(rhs.m_nHigh));
193 }
194};
195
197{
200 sal_uInt32 m_nAddr;
201
204 explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
205 : m_nAddr (store::htonl(nAddr))
206 {}
207
208 void swap (OStorePageLink & rhs)
209 {
210 std::swap(m_nAddr, rhs.m_nAddr);
211 }
212
213 OStorePageLink & operator= (sal_uInt32 nAddr)
214 {
215 m_nAddr = store::htonl(nAddr);
216 return *this;
217 }
218
221 bool operator== (const OStorePageLink & rhs) const
222 {
223 return (m_nAddr == rhs.m_nAddr);
224 }
225
228 sal_uInt32 location() const
229 {
230 return store::ntohl(m_nAddr);
231 }
232
233};
234
236{
240
247
250 static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L);
251 static const sal_uInt16 thePageSize = theSize;
252 static_assert(STORE_MINIMUM_PAGESIZE >= thePageSize, "must be at least thePageSize");
253
256 sal_uInt32 location() const
257 {
259 }
260 void location (sal_uInt32 nAddr)
261 {
263 }
264
267 sal_uInt16 size() const
268 {
270 }
271
274 sal_uInt32 type() const
275 {
277 }
278
281 class Allocator_Impl;
283 {
284 public:
285 template< class T > T * construct()
286 {
287 void * page = nullptr;
288 sal_uInt16 nSize = 0;
289 if (allocate (&page, &nSize))
290 {
291 return new(page) T(nSize);
292 }
293 return nullptr;
294 }
295
296 bool allocate (void ** ppPage, sal_uInt16 * pnSize)
297 {
298 allocate_Impl (ppPage, pnSize);
299 return ((*ppPage != nullptr) && (*pnSize != 0));
300 }
301
302 void deallocate (void * pPage)
303 {
304 if (pPage != nullptr)
305 deallocate_Impl (pPage);
306 }
307
309 rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
310
311 protected:
312 virtual ~Allocator() override {}
313
314 private:
317 virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) = 0;
318 virtual void deallocate_Impl (void * pPage) = 0;
319 };
320
322 public:
324 allocator_(std::move(allocator)) {};
325
326 void operator ()(void * page) const { allocator_->deallocate(page); }
327
328 private:
330 };
331
332 static void* operator new (size_t, void * p) { return p; }
333 static void operator delete (void * , void *) {}
334
337 explicit PageData (sal_uInt16 nPageSize = thePageSize)
338 : m_aGuard(),
340 m_aMarked(),
341 m_aUnused()
342 {}
343
344 void swap (PageData & rhs) // nothrow
345 {
350 }
351
352 PageData (PageData const & rhs) // nothrow
353 : m_aGuard (rhs.m_aGuard),
354 m_aDescr (rhs.m_aDescr),
355 m_aMarked(rhs.m_aMarked),
357 {}
358
359 PageData & operator= (PageData const & rhs) // nothrow
360 {
361 PageData tmp (rhs);
362 swap (tmp);
363 return *this;
364 }
365
368 void guard (sal_uInt32 nAddr)
369 {
370 sal_uInt32 nCRC32 = rtl_crc32 (0, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
372 nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, static_cast<sal_uInt32>(theSize - sizeof(G)));
374 }
375
378 storeError verify (sal_uInt32 nAddr) const
379 {
380 sal_uInt32 nCRC32 = rtl_crc32 (0, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
381 nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, static_cast<sal_uInt32>(theSize - sizeof(G)));
382 if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
384 if (m_aDescr.m_nAddr != store::htonl(nAddr))
386 return store_E_None;
387 }
388
389};
390
391template< class T >
393{
396 std::shared_ptr<PageData> m_xPage;
397
400 template< class U >
401 static bool isA (PageData const * p)
402 {
403 return ((p != nullptr) && (p->type() == U::theTypeId));
404 }
405
406 template< class U >
408 {
409 return isA<U>(p) ? static_cast<U*>(p) : nullptr;
410 }
411
412 template< class U >
413 static U const * dynamic_page_cast (PageData const * p)
414 {
415 return isA<U>(p) ? static_cast<U const *>(p) : nullptr;
416 }
417
418public:
420 {
421 if (!m_xPage && rxAllocator.is())
422 {
423 std::shared_ptr<PageData> tmp (rxAllocator->construct<T>(), PageData::Deallocate(rxAllocator));
424 m_xPage.swap (tmp);
425 }
426 return bool(m_xPage);
427 }
428
429 explicit PageHolderObject (std::shared_ptr<PageData> xPage = std::shared_ptr<PageData>())
430 : m_xPage (std::move(xPage))
431 {}
432
434 {
435 m_xPage.swap (rhs.m_xPage);
436 }
437
439 : m_xPage (rhs.m_xPage)
440 {}
441
443 {
444 PageHolderObject<T> tmp (rhs);
445 this->swap (tmp);
446 return *this;
447 }
448
449 bool is() const
450 {
451 return bool(m_xPage);
452 }
453
454 std::shared_ptr<PageData> & get() { return m_xPage; }
455 std::shared_ptr<PageData> const & get() const { return m_xPage; }
456
458 {
459 T * pImpl = dynamic_page_cast<T>(m_xPage.get());
460 OSL_PRECOND(pImpl != nullptr, "store::PageHolder<T>::operator*(): Null pointer");
461 return pImpl;
462 }
463
464 T const * operator->() const
465 {
466 T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
467 OSL_PRECOND(pImpl != nullptr, "store::PageHolder<T>::operator*(): Null pointer");
468 return pImpl;
469 }
470
472 {
473 T * pImpl = dynamic_page_cast<T>(m_xPage.get());
474 OSL_PRECOND(pImpl != nullptr, "store::PageHolder<T>::operator*(): Null pointer");
475 return (*pImpl);
476 }
477
478 T const & operator*() const
479 {
480 T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
481 OSL_PRECOND(pImpl != nullptr, "store::PageHolder<T>::operator*(): Null pointer");
482 return (*pImpl);
483 }
484
485 static storeError guard (std::shared_ptr<PageData> const & rxPage, sal_uInt32 nAddr)
486 {
487 PageData * pHead = rxPage.get();
488 if (!pHead)
490 pHead->guard(nAddr);
491
492 T * pImpl = dynamic_page_cast<T>(pHead);
493 OSL_PRECOND(pImpl != nullptr, "store::PageHolder<T>::guard(): Null pointer");
494 pImpl->guard();
495
496 return store_E_None;
497 }
498
499 static storeError verify (std::shared_ptr<PageData> const & rxPage, sal_uInt32 nAddr)
500 {
501 PageData const * pHead = rxPage.get();
502 if (!pHead)
504
505 storeError eErrCode = pHead->verify(nAddr);
506 if (eErrCode != store_E_None)
507 return eErrCode;
508
509 T const * pImpl = dynamic_page_cast<T>(pHead);
510 if (!pImpl)
512
513 return pImpl->verify();
514 }
515};
516
518{
519 typedef PageData page;
520
521public:
524 static void * operator new (size_t n)
525 {
526 return std::malloc(sal_uInt32(n));
527 }
528 static void operator delete (void * p)
529 {
530 std::free (p);
531 }
532
535 inline bool dirty() const;
536 inline void clean();
537 inline void touch();
538
541 inline sal_uInt32 location() const;
542
543protected:
546 std::shared_ptr<PageData> m_xPage;
548
551 explicit OStorePageObject (std::shared_ptr<PageData> rxPage)
552 : m_xPage (std::move(rxPage)), m_bDirty (false)
553 {}
554
557 virtual ~OStorePageObject();
558
559public:
560 template< class U >
562 {
564 }
565
566 template< class U >
568 {
569 if (!rxAllocator.is())
571
572 std::shared_ptr<PageData> tmp (rxAllocator->construct<U>(), PageData::Deallocate(rxAllocator));
573 if (!tmp)
574 return store_E_OutOfMemory;
575
576 m_xPage.swap (tmp);
577 return store_E_None;
578 }
579
580 std::shared_ptr<PageData> & get() { return m_xPage; }
581
582 virtual storeError guard (sal_uInt32 nAddr) = 0;
583 virtual storeError verify (sal_uInt32 nAddr) const = 0;
584};
585
586inline bool OStorePageObject::dirty() const
587{
588 return m_bDirty;
589}
590
592{
593 m_bDirty = false;
594}
595
597{
598 m_bDirty = true;
599}
600
601inline sal_uInt32 OStorePageObject::location() const
602{
603 return m_xPage->location();
604}
605
606} // namespace store
607
608/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
storeError construct(rtl::Reference< PageData::Allocator > const &rxAllocator)
Definition: storbase.hxx:567
virtual ~OStorePageObject()
Destruction.
Definition: storbase.cxx:120
virtual storeError guard(sal_uInt32 nAddr)=0
bool dirty() const
State.
Definition: storbase.hxx:586
sal_uInt32 location() const
Location.
Definition: storbase.hxx:601
virtual storeError verify(sal_uInt32 nAddr) const =0
PageHolderObject< U > makeHolder() const
Definition: storbase.hxx:561
std::shared_ptr< PageData > & get()
Definition: storbase.hxx:580
std::shared_ptr< PageData > m_xPage
Representation.
Definition: storbase.hxx:546
OStorePageObject(std::shared_ptr< PageData > rxPage)
Construction.
Definition: storbase.hxx:551
virtual void deallocate_Impl(void *pPage)=0
static storeError createInstance(rtl::Reference< PageData::Allocator > &rxAllocator, sal_uInt16 nPageSize)
Definition: storbase.cxx:110
void deallocate(void *pPage)
Definition: storbase.hxx:302
bool allocate(void **ppPage, sal_uInt16 *pnSize)
Definition: storbase.hxx:296
virtual ~Allocator() override
Definition: storbase.hxx:312
virtual void allocate_Impl(void **ppPage, sal_uInt16 *pnSize)=0
Implementation (abstract).
Deallocate(rtl::Reference< Allocator > allocator)
Definition: storbase.hxx:323
rtl::Reference< Allocator > allocator_
Definition: storbase.hxx:329
void operator()(void *page) const
Definition: storbase.hxx:326
std::shared_ptr< PageData > const & get() const
Definition: storbase.hxx:455
bool construct(rtl::Reference< PageData::Allocator > const &rxAllocator)
Definition: storbase.hxx:419
T const & operator*() const
Definition: storbase.hxx:478
static bool isA(PageData const *p)
Checked cast.
Definition: storbase.hxx:401
void swap(PageHolderObject< T > &rhs)
Definition: storbase.hxx:433
static U const * dynamic_page_cast(PageData const *p)
Definition: storbase.hxx:413
static storeError verify(std::shared_ptr< PageData > const &rxPage, sal_uInt32 nAddr)
Definition: storbase.hxx:499
static storeError guard(std::shared_ptr< PageData > const &rxPage, sal_uInt32 nAddr)
Definition: storbase.hxx:485
PageHolderObject(std::shared_ptr< PageData > xPage=std::shared_ptr< PageData >())
Definition: storbase.hxx:429
std::shared_ptr< PageData > m_xPage
Representation.
Definition: storbase.hxx:396
std::shared_ptr< PageData > & get()
Definition: storbase.hxx:454
PageHolderObject< T > & operator=(PageHolderObject< T > const &rhs)
Definition: storbase.hxx:442
static U * dynamic_page_cast(PageData *p)
Definition: storbase.hxx:407
T const * operator->() const
Definition: storbase.hxx:464
PageHolderObject(PageHolderObject< T > const &rhs)
Definition: storbase.hxx:438
void * p
sal_Int64 n
Old OStorePageCache implementation.
Definition: lockbyte.cxx:133
sal_uInt32 htonl(sal_uInt32 h)
Definition: storbase.hxx:69
sal_uInt16 ntohs(sal_uInt16 n)
Definition: storbase.hxx:67
sal_uInt32 ntohl(sal_uInt32 n)
Definition: storbase.hxx:70
sal_uInt16 htons(sal_uInt16 h)
Definition: storbase.hxx:66
sal_Int32 h
const sal_uInt16 nMagic
#define STORE_PAGE_NULL
Definition: storbase.hxx:114
void swap(OStorePageDescriptor &rhs)
Definition: storbase.hxx:135
OStorePageDescriptor & operator=(const OStorePageDescriptor &rhs)
Definition: storbase.hxx:148
bool operator==(const OStorePageDescriptor &rhs) const
Comparison.
Definition: storbase.hxx:158
OStorePageDescriptor(sal_uInt32 nAddr, sal_uInt16 nSize, sal_uInt16 nUsed)
Construction.
Definition: storbase.hxx:126
sal_uInt32 m_nAddr
Representation.
Definition: storbase.hxx:120
OStorePageDescriptor(const OStorePageDescriptor &rhs)
Definition: storbase.hxx:142
bool operator==(const OStorePageGuard &rhs) const
Comparison.
Definition: storbase.hxx:107
OStorePageGuard(sal_uInt32 nMagic=0)
Construction.
Definition: storbase.hxx:82
void swap(OStorePageGuard &rhs)
Definition: storbase.hxx:87
sal_uInt32 m_nMagic
Representation.
Definition: storbase.hxx:77
OStorePageGuard & operator=(const OStorePageGuard &rhs)
Definition: storbase.hxx:98
OStorePageGuard(OStorePageGuard const &rhs)
Definition: storbase.hxx:93
sal_uInt32 m_nLow
Representation.
Definition: storbase.hxx:169
bool operator==(const OStorePageKey &rhs) const
Comparison.
Definition: storbase.hxx:181
OStorePageKey(sal_uInt32 nLow=0, sal_uInt32 nHigh=0)
Construction.
Definition: storbase.hxx:174
sal_uInt32 m_nHigh
Definition: storbase.hxx:170
bool operator<(const OStorePageKey &rhs) const
Definition: storbase.hxx:187
G m_aGuard
Representation.
Definition: storbase.hxx:243
PageData(PageData const &rhs)
Definition: storbase.hxx:352
void guard(sal_uInt32 nAddr)
guard (external representation).
Definition: storbase.hxx:368
sal_uInt16 size() const
size.
Definition: storbase.hxx:267
sal_uInt32 type() const
type.
Definition: storbase.hxx:274
PageData(sal_uInt16 nPageSize=thePageSize)
Construction.
Definition: storbase.hxx:337
OStorePageDescriptor D
Definition: storbase.hxx:238
void swap(PageData &rhs)
Definition: storbase.hxx:344
OStorePageGuard G
Definition: storbase.hxx:237
OStorePageLink L
Definition: storbase.hxx:239
storeError verify(sal_uInt32 nAddr) const
verify (external representation).
Definition: storbase.hxx:378
PageData & operator=(PageData const &rhs)
Definition: storbase.hxx:359
static const sal_uInt16 thePageSize
Definition: storbase.hxx:251
sal_uInt32 location() const
location.
Definition: storbase.hxx:256
static const size_t theSize
theSize.
Definition: storbase.hxx:250
void location(sal_uInt32 nAddr)
Definition: storbase.hxx:260
constexpr sal_uInt16 STORE_MINIMUM_PAGESIZE
PageSize (enforced) limits.
Definition: types.h:37
storeError
Error Code enumeration.
Definition: types.h:73
@ store_E_WrongVersion
Definition: types.h:94
@ store_E_OutOfMemory
Definition: types.h:90
@ store_E_None
Definition: types.h:74
@ store_E_InvalidAccess
Definition: types.h:80
@ store_E_InvalidChecksum
Definition: types.h:83