LibreOffice Module store (master) 1
stordata.cxx
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#include "stordata.hxx"
21
22#include <sal/types.h>
23#include <sal/log.hxx>
24
25#include <store/types.h>
26#include "storbase.hxx"
27#include "storbios.hxx"
28
29using namespace store;
30
31storeError OStoreDataPageObject::guard (sal_uInt32 nAddr)
32{
34}
35
37{
39}
40
45 sal_uInt32 nAddr,
46 sal_uInt16 nSingle,
47 OStorePageBIOS &rBIOS)
48{
49 if (nAddr != STORE_PAGE_NULL)
50 {
51 // Load single indirect page.
53 storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
54 if (eErrCode == store_E_None)
55 {
56 // Truncate to 'nSingle' direct pages.
57 eErrCode = aSingle.truncate (nSingle, rBIOS);
58 if (eErrCode != store_E_None)
59 return eErrCode;
60 }
61 else
62 {
63 if (eErrCode != store_E_InvalidChecksum)
64 return eErrCode;
65 }
66
67 // Check for complete truncation.
68 if (nSingle == 0)
69 {
70 // Free single indirect page.
71 eErrCode = rBIOS.free (nAddr);
72 if (eErrCode != store_E_None)
73 return eErrCode;
74 }
75 }
76 return store_E_None;
77}
78
79/*
80 * store_truncate_Impl (double indirect page).
81 */
83 sal_uInt32 nAddr,
84 sal_uInt16 nDouble,
85 sal_uInt16 nSingle,
86 OStorePageBIOS &rBIOS)
87{
88 if (nAddr != STORE_PAGE_NULL)
89 {
90 // Load double indirect page.
92 storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
93 if (eErrCode == store_E_None)
94 {
95 // Truncate to 'nDouble', 'nSingle' pages.
96 eErrCode = aDouble.truncate (nDouble, nSingle, rBIOS);
97 if (eErrCode != store_E_None)
98 return eErrCode;
99 }
100 else
101 {
102 if (eErrCode != store_E_InvalidChecksum)
103 return eErrCode;
104 }
105
106 // Check for complete truncation.
107 if ((nDouble + nSingle) == 0)
108 {
109 // Free double indirect page.
110 eErrCode = rBIOS.free (nAddr);
111 if (eErrCode != store_E_None)
112 return eErrCode;
113 }
114 }
115 return store_E_None;
116}
117
118/*
119 * store_truncate_Impl (triple indirect page).
120 */
122 sal_uInt32 nAddr,
123 sal_uInt16 nTriple,
124 sal_uInt16 nDouble,
125 sal_uInt16 nSingle,
126 OStorePageBIOS &rBIOS)
127{
128 if (nAddr != STORE_PAGE_NULL)
129 {
130 // Load triple indirect page.
132 storeError eErrCode = rBIOS.loadObjectAt (aTriple, nAddr);
133 if (eErrCode != store_E_None)
134 return eErrCode;
135
136 // Truncate to 'nTriple', 'nDouble', 'nSingle' pages.
137 eErrCode = aTriple.truncate (nTriple, nDouble, nSingle, rBIOS);
138 if (eErrCode != store_E_None)
139 return eErrCode;
140
141 // Check for complete truncation.
142 if ((nTriple + nDouble + nSingle) == 0)
143 {
144 // Free triple indirect page.
145 eErrCode = rBIOS.free (nAddr);
146 if (eErrCode != store_E_None)
147 return eErrCode;
148 }
149 }
150 return store_E_None;
151}
152
154 sal_uInt32 nAddr,
155 OStorePageBIOS & rBIOS)
156{
157 if (nAddr == STORE_PAGE_NULL)
158 {
159 storeError eErrCode = construct<page>(rBIOS.allocator());
160 if (eErrCode != store_E_None)
161 return eErrCode;
162
163 eErrCode = rBIOS.allocate (*this);
164 if (eErrCode != store_E_None)
165 return eErrCode;
166
167 // Save location pending at caller.
168 return store_E_Pending;
169 }
170 return rBIOS.loadObjectAt (*this, nAddr);
171}
172
174{
176}
177
179{
181}
182
184 sal_uInt16 nSingle,
186 OStorePageBIOS &rBIOS) const
187{
189 page const & rPage = *xImpl;
190
191 // Check arguments.
192 sal_uInt16 const nLimit = rPage.capacityCount();
193 if (nSingle >= nLimit)
195
196 // Obtain data page location.
197 sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]);
198 if (nAddr == STORE_PAGE_NULL)
199 return store_E_NotExists;
200
201 // Load data page and leave.
202 return rBIOS.loadObjectAt (rData, nAddr);
203}
204
205/*
206 * read (double indirect).
207 */
209 sal_uInt16 nDouble,
210 sal_uInt16 nSingle,
212 OStorePageBIOS &rBIOS) const
213{
215 page const & rPage = *xImpl;
216
217 // Check arguments.
218 sal_uInt16 const nLimit = rPage.capacityCount();
219 if ((nDouble >= nLimit) || (nSingle >= nLimit))
221
222 // Check single indirect page location.
223 sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nDouble]);
224 if (nAddr == STORE_PAGE_NULL)
225 return store_E_NotExists;
226
227 // Load single indirect page.
229 storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
230 if (eErrCode != store_E_None)
231 return eErrCode;
232
233 // Read single indirect and leave.
234 return aSingle.read (nSingle, rData, rBIOS);
235}
236
237/*
238 * read (triple indirect).
239 */
241 sal_uInt16 nTriple,
242 sal_uInt16 nDouble,
243 sal_uInt16 nSingle,
245 OStorePageBIOS &rBIOS) const
246{
248 page const & rPage = *xImpl;
249
250 // Check arguments.
251 sal_uInt16 const nLimit = rPage.capacityCount();
252 if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
254
255 // Check double indirect page location.
256 sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nTriple]);
257 if (nAddr == STORE_PAGE_NULL)
258 return store_E_NotExists;
259
260 // Load double indirect page.
262 storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
263 if (eErrCode != store_E_None)
264 return eErrCode;
265
266 // Read double indirect and leave.
267 return aDouble.read (nDouble, nSingle, rData, rBIOS);
268}
269
270/*
271 * write (single indirect).
272 */
274 sal_uInt16 nSingle,
276 OStorePageBIOS &rBIOS)
277{
279 page & rPage = *xImpl;
280
281 // Check arguments.
282 sal_uInt16 const nLimit = rPage.capacityCount();
283 if (nSingle >= nLimit)
285
286 // Obtain data page location.
287 sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]);
288 if (nAddr == STORE_PAGE_NULL)
289 {
290 // Allocate data page.
291 storeError eErrCode = rBIOS.allocate (rData);
292 if (eErrCode != store_E_None)
293 return eErrCode;
294
295 // Store data page location.
296 rPage.m_pData[nSingle] = store::htonl(rData.location());
297
298 // Save this page.
299 return rBIOS.saveObjectAt (*this, location());
300 }
301 else
302 {
303 // Save data page.
304 return rBIOS.saveObjectAt (rData, nAddr);
305 }
306}
307
308/*
309 * write (double indirect).
310 */
312 sal_uInt16 nDouble,
313 sal_uInt16 nSingle,
315 OStorePageBIOS &rBIOS)
316{
318 page & rPage = *xImpl;
319
320 // Check arguments.
321 sal_uInt16 const nLimit = rPage.capacityCount();
322 if ((nDouble >= nLimit) || (nSingle >= nLimit))
324
325 // Load or create single indirect page.
327 storeError eErrCode = aSingle.loadOrCreate (store::ntohl(rPage.m_pData[nDouble]), rBIOS);
328 if (eErrCode != store_E_None)
329 {
330 if (eErrCode != store_E_Pending)
331 return eErrCode;
332 rPage.m_pData[nDouble] = store::htonl(aSingle.location());
333
334 eErrCode = rBIOS.saveObjectAt (*this, location());
335 if (eErrCode != store_E_None)
336 return eErrCode;
337 }
338
339 // Write single indirect and leave.
340 return aSingle.write (nSingle, rData, rBIOS);
341}
342
343/*
344 * write (triple indirect).
345 */
347 sal_uInt16 nTriple,
348 sal_uInt16 nDouble,
349 sal_uInt16 nSingle,
351 OStorePageBIOS &rBIOS)
352{
354 page & rPage = *xImpl;
355
356 // Check arguments.
357 sal_uInt16 const nLimit = rPage.capacityCount();
358 if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
360
361 // Load or create double indirect page.
363 storeError eErrCode = aDouble.loadOrCreate (store::ntohl(rPage.m_pData[nTriple]), rBIOS);
364 if (eErrCode != store_E_None)
365 {
366 if (eErrCode != store_E_Pending)
367 return eErrCode;
368 rPage.m_pData[nTriple] = store::htonl(aDouble.location());
369
370 eErrCode = rBIOS.saveObjectAt (*this, location());
371 if (eErrCode != store_E_None)
372 return eErrCode;
373 }
374
375 // Write double indirect and leave.
376 return aDouble.write (nDouble, nSingle, rData, rBIOS);
377}
378
379/*
380 * truncate (single indirect).
381 */
383 sal_uInt16 nSingle,
384 OStorePageBIOS & rBIOS)
385{
387 page & rPage = *xImpl;
388
389 // Check arguments.
390 sal_uInt16 const nLimit = rPage.capacityCount();
391 if (nSingle >= nLimit)
393
394 // Truncate.
395 storeError eErrCode = store_E_None;
396 for (sal_uInt16 i = nLimit; i > nSingle; i--)
397 {
398 // Obtain data page location.
399 sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[i - 1]);
400 if (nAddr != STORE_PAGE_NULL)
401 {
402 // Free data page.
403 eErrCode = rBIOS.free (nAddr);
404 if (eErrCode != store_E_None)
405 return eErrCode;
406
407 // Clear pointer to data page.
408 rPage.m_pData[i - 1] = STORE_PAGE_NULL;
409 touch();
410 }
411 }
412
413 // Check for modified page.
414 if (dirty())
415 {
416 // Save this page.
417 eErrCode = rBIOS.saveObjectAt (*this, location());
418 }
419
420 // Done.
421 return eErrCode;
422}
423
424/*
425 * truncate (double indirect).
426 */
428 sal_uInt16 nDouble,
429 sal_uInt16 nSingle,
430 OStorePageBIOS &rBIOS)
431{
433 page & rPage = *xImpl;
434
435 // Check arguments.
436 sal_uInt16 const nLimit = rPage.capacityCount();
437 if ((nDouble >= nLimit) || (nSingle >= nLimit))
439
440 // Truncate.
441 storeError eErrCode = store_E_None;
442 for (sal_uInt16 i = nLimit; i > nDouble + 1; i--)
443 {
444 // Truncate single indirect page to zero direct pages.
445 eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, rBIOS);
446 if (eErrCode != store_E_None)
447 return eErrCode;
448
449 // Clear pointer to single indirect page.
450 rPage.m_pData[i - 1] = STORE_PAGE_NULL;
451 touch();
452 }
453
454 // Truncate last single indirect page to 'nSingle' direct pages.
455 eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nDouble]), nSingle, rBIOS);
456 if (eErrCode != store_E_None)
457 return eErrCode;
458
459 // Check for complete truncation.
460 if (nSingle == 0)
461 {
462 // Clear pointer to last single indirect page.
463 rPage.m_pData[nDouble] = STORE_PAGE_NULL;
464 touch();
465 }
466
467 // Check for modified page.
468 if (dirty())
469 {
470 // Save this page.
471 eErrCode = rBIOS.saveObjectAt (*this, location());
472 }
473
474 // Done.
475 return eErrCode;
476}
477
478/*
479 * truncate (triple indirect).
480 */
482 sal_uInt16 nTriple,
483 sal_uInt16 nDouble,
484 sal_uInt16 nSingle,
485 OStorePageBIOS &rBIOS)
486{
488 page & rPage = *xImpl;
489
490 // Check arguments.
491 sal_uInt16 const nLimit = rPage.capacityCount();
492 if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit)))
494
495 // Truncate.
496 storeError eErrCode = store_E_None;
497 for (sal_uInt16 i = nLimit; i > nTriple + 1; i--)
498 {
499 // Truncate double indirect page to zero single indirect pages.
500 eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, 0, rBIOS);
501 if (eErrCode != store_E_None)
502 return eErrCode;
503
504 // Clear pointer to double indirect page.
505 rPage.m_pData[i - 1] = STORE_PAGE_NULL;
506 touch();
507 }
508
509 // Truncate last double indirect page to 'nDouble', 'nSingle' pages.
510 eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nTriple]), nDouble, nSingle, rBIOS);
511 if (eErrCode != store_E_None)
512 return eErrCode;
513
514 // Check for complete truncation.
515 if ((nDouble + nSingle) == 0)
516 {
517 // Clear pointer to last double indirect page.
518 rPage.m_pData[nTriple] = STORE_PAGE_NULL;
519 touch();
520 }
521
522 // Check for modified page.
523 if (dirty())
524 {
525 // Save this page.
526 eErrCode = rBIOS.saveObjectAt (*this, location());
527 }
528
529 // Done.
530 return eErrCode;
531}
532
534{
536}
537
539{
541}
542
545 sal_uInt32 nPage,
546 page::DataBlock::LinkDescriptor &rDescr) const
547{
548 page const & rPage = PAGE();
549
550 sal_uInt32 index0, index1, index2;
551
552 // direct.
554 sal_uInt32 nLimit = nCount;
555 if (nPage < nLimit)
556 {
557 // Page to index reduction.
558 index0 = nPage;
559
560 // Setup LinkDescriptor indices.
561 rDescr.m_nIndex0 = static_cast<sal_uInt16>(index0 & 0xffff);
562
563 // Done.
564 return page::SCOPE_DIRECT;
565 }
566 nPage -= nLimit;
567
568 // single indirect.
569 sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr);
571 nLimit = nCount * nCapacity;
572 if (nPage < nLimit)
573 {
574 // Page to index reduction.
575 sal_uInt32 n = nPage;
576
577 // Reduce to single indirect i(1), direct n = i(0).
578 index1 = n / nCapacity;
579 index0 = n % nCapacity;
580
581 // Verify reduction.
582 n = index1 * nCapacity + index0;
583 if (n != nPage)
584 {
585 SAL_WARN("store", "wrong math on indirect indices");
586 return page::SCOPE_UNKNOWN;
587 }
588
589 // Setup LinkDescriptor indices.
590 rDescr.m_nIndex0 = static_cast<sal_uInt16>(index0 & 0xffff);
591 rDescr.m_nIndex1 = static_cast<sal_uInt16>(index1 & 0xffff);
592
593 // Done.
594 return page::SCOPE_SINGLE;
595 }
596 nPage -= nLimit;
597
598 // double indirect.
600 nLimit = nCount * nCapacity * nCapacity;
601 if (nPage < nLimit)
602 {
603 // Page to index reduction.
604 sal_uInt32 n = nPage;
605
606 // Reduce to double indirect i(2), single indirect n = i(0).
607 index2 = n / (nCapacity * nCapacity);
608 n = n % (nCapacity * nCapacity);
609
610 // Reduce to single indirect i(1), direct n = i(0).
611 index1 = n / nCapacity;
612 index0 = n % nCapacity;
613
614 // Verify reduction.
615 n = index2 * nCapacity * nCapacity +
616 index1 * nCapacity + index0;
617 if (n != nPage)
618 {
619 SAL_WARN("store", "wrong math on double indirect indices");
620 return page::SCOPE_UNKNOWN;
621 }
622
623 // Setup LinkDescriptor indices.
624 rDescr.m_nIndex0 = static_cast<sal_uInt16>(index0 & 0xffff);
625 rDescr.m_nIndex1 = static_cast<sal_uInt16>(index1 & 0xffff);
626 rDescr.m_nIndex2 = static_cast<sal_uInt16>(index2 & 0xffff);
627
628 // Done.
629 return page::SCOPE_DOUBLE;
630 }
631 nPage -= nLimit;
632
633 // triple indirect.
635 nLimit = nCount * nCapacity * nCapacity * nCapacity;
636 if (nPage < nLimit)
637 {
638 // Page to index reduction.
639 sal_uInt32 n = nPage;
640
641 // Reduce to triple indirect i(3), double indirect n.
642 sal_uInt32 index3 = n / (nCapacity * nCapacity * nCapacity);
643 n = n % (nCapacity * nCapacity * nCapacity);
644
645 // Reduce to double indirect i(2), single indirect n.
646 index2 = n / (nCapacity * nCapacity);
647 n = n % (nCapacity * nCapacity);
648
649 // Reduce to single indirect i(1), direct n = i(0).
650 index1 = n / nCapacity;
651 index0 = n % nCapacity;
652
653 // Verify reduction.
654 n = index3 * nCapacity * nCapacity * nCapacity +
655 index2 * nCapacity * nCapacity +
656 index1 * nCapacity + index0;
657 if (n != nPage)
658 {
659 SAL_WARN("store", "wrong math on triple indirect indices");
660 return page::SCOPE_UNKNOWN;
661 }
662
663 // Setup LinkDescriptor indices.
664 rDescr.m_nIndex0 = static_cast<sal_uInt16>(index0 & 0xffff);
665 rDescr.m_nIndex1 = static_cast<sal_uInt16>(index1 & 0xffff);
666 rDescr.m_nIndex2 = static_cast<sal_uInt16>(index2 & 0xffff);
667 rDescr.m_nIndex3 = static_cast<sal_uInt16>(index3 & 0xffff);
668
669 // Done.
670 return page::SCOPE_TRIPLE;
671 }
672
673 // Unreachable (more than triple indirect).
675}
676
678 sal_uInt32 nPage,
680 OStorePageBIOS &rBIOS) const
681{
682 // Determine scope and link indices.
683 page::DataBlock::LinkDescriptor aLink;
684 page::ChunkScope eScope = scope (nPage, aLink);
685
686 storeError eErrCode = store_E_None;
687 if (eScope == page::SCOPE_DIRECT)
688 {
689 sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
690 if (nAddr == STORE_PAGE_NULL)
691 return store_E_NotExists;
692
693 eErrCode = rBIOS.loadObjectAt (rData, nAddr);
694 }
695 else if (eScope == page::SCOPE_SINGLE)
696 {
697 sal_uInt32 const nAddr = singleLink (aLink.m_nIndex1);
698 if (nAddr == STORE_PAGE_NULL)
699 return store_E_NotExists;
700
702 eErrCode = rBIOS.loadObjectAt (aSingle, nAddr);
703 if (eErrCode != store_E_None)
704 return eErrCode;
705
706 eErrCode = aSingle.read (aLink.m_nIndex0, rData, rBIOS);
707 }
708 else if (eScope == page::SCOPE_DOUBLE)
709 {
710 sal_uInt32 const nAddr = doubleLink (aLink.m_nIndex2);
711 if (nAddr == STORE_PAGE_NULL)
712 return store_E_NotExists;
713
715 eErrCode = rBIOS.loadObjectAt (aDouble, nAddr);
716 if (eErrCode != store_E_None)
717 return eErrCode;
718
719 eErrCode = aDouble.read (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
720 }
721 else if (eScope == page::SCOPE_TRIPLE)
722 {
723 sal_uInt32 const nAddr = tripleLink (aLink.m_nIndex3);
724 if (nAddr == STORE_PAGE_NULL)
725 return store_E_NotExists;
726
728 eErrCode = rBIOS.loadObjectAt (aTriple, nAddr);
729 if (eErrCode != store_E_None)
730 return eErrCode;
731
732 eErrCode = aTriple.read (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
733 }
734 else if (eScope == page::SCOPE_UNREACHABLE)
735 {
736 // Out of scope.
737 eErrCode = store_E_CantSeek;
738 }
739 else
740 {
741 // Unknown scope.
742 SAL_WARN("store", "OStoreDirectoryPageObject::get(): scope failed");
743 eErrCode = store_E_Unknown;
744 }
745
746 // Leave.
747 return eErrCode;
748}
749
751 sal_uInt32 nPage,
753 OStorePageBIOS &rBIOS)
754{
755 // Determine scope and link indices.
756 page::DataBlock::LinkDescriptor aLink;
757 page::ChunkScope eScope = scope (nPage, aLink);
758
759 storeError eErrCode = store_E_None;
760 if (eScope == page::SCOPE_DIRECT)
761 {
762 sal_uInt32 const nAddr = directLink (aLink.m_nIndex0);
763 if (nAddr == STORE_PAGE_NULL)
764 {
765 // Allocate data page.
766 eErrCode = rBIOS.allocate (rData);
767 if (eErrCode != store_E_None)
768 return eErrCode;
769
770 // Store data page location.
771 directLink (aLink.m_nIndex0, rData.location());
772 }
773 else
774 {
775 // Save data page.
776 eErrCode = rBIOS.saveObjectAt (rData, nAddr);
777 }
778 }
779 else if (eScope == page::SCOPE_SINGLE)
780 {
782 eErrCode = aSingle.loadOrCreate (singleLink (aLink.m_nIndex1), rBIOS);
783 if (eErrCode != store_E_None)
784 {
785 if (eErrCode != store_E_Pending)
786 return eErrCode;
787 singleLink (aLink.m_nIndex1, aSingle.location());
788 }
789
790 eErrCode = aSingle.write (aLink.m_nIndex0, rData, rBIOS);
791 }
792 else if (eScope == page::SCOPE_DOUBLE)
793 {
795 eErrCode = aDouble.loadOrCreate (doubleLink (aLink.m_nIndex2), rBIOS);
796 if (eErrCode != store_E_None)
797 {
798 if (eErrCode != store_E_Pending)
799 return eErrCode;
800 doubleLink (aLink.m_nIndex2, aDouble.location());
801 }
802
803 eErrCode = aDouble.write (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
804 }
805 else if (eScope == page::SCOPE_TRIPLE)
806 {
808 eErrCode = aTriple.loadOrCreate (tripleLink (aLink.m_nIndex3), rBIOS);
809 if (eErrCode != store_E_None)
810 {
811 if (eErrCode != store_E_Pending)
812 return eErrCode;
813 tripleLink (aLink.m_nIndex3, aTriple.location());
814 }
815
816 eErrCode = aTriple.write (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS);
817 }
818 else if (eScope == page::SCOPE_UNREACHABLE)
819 {
820 // Out of scope.
821 eErrCode = store_E_CantSeek;
822 }
823 else
824 {
825 // Unknown scope.
826 SAL_WARN("store", "OStoreDirectoryPageObject::put(): scope failed");
827 eErrCode = store_E_Unknown;
828 }
829
830 // Leave.
831 return eErrCode;
832}
833
835 sal_uInt32 nPage,
836 OStorePageBIOS &rBIOS)
837{
838 // Determine scope and link indices.
839 page::DataBlock::LinkDescriptor aLink;
840 page::ChunkScope eScope = scope (nPage, aLink);
841
842 storeError eErrCode = store_E_None;
843 if (eScope == page::SCOPE_DIRECT)
844 {
845 // Truncate all triple indirect pages.
846 eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
847 if (eErrCode != store_E_None)
848 return eErrCode;
849
850 // Truncate all double indirect pages.
851 eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
852 if (eErrCode != store_E_None)
853 return eErrCode;
854
855 // Truncate all single indirect pages.
856 eErrCode = truncate (page::SCOPE_SINGLE, 0, rBIOS);
857 if (eErrCode != store_E_None)
858 return eErrCode;
859
860 // Truncate direct pages, including 'aLink.m_nIndex0'.
861 eErrCode = truncate (eScope, aLink.m_nIndex0, rBIOS);
862 }
863 else if (eScope == page::SCOPE_SINGLE)
864 {
865 // Truncate all triple indirect pages.
866 eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
867 if (eErrCode != store_E_None)
868 return eErrCode;
869
870 // Truncate all double indirect pages.
871 eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS);
872 if (eErrCode != store_E_None)
873 return eErrCode;
874
875 // Truncate single indirect pages, downto 'aLink.m_nIndex1'.
876 eErrCode = truncate (eScope, aLink.m_nIndex1 + 1, rBIOS);
877 if (eErrCode != store_E_None)
878 return eErrCode;
879
880 // Truncate last single indirect page to ... pages.
881 eErrCode = store_truncate_Impl (singleLink (aLink.m_nIndex1), aLink.m_nIndex0, rBIOS);
882 if (eErrCode != store_E_None)
883 return eErrCode;
884
885 // Check for complete truncation.
886 if (aLink.m_nIndex0 == 0)
887 {
888 // Clear pointer to last single indirect page.
889 singleLink (aLink.m_nIndex1, STORE_PAGE_NULL);
890 }
891 }
892 else if (eScope == page::SCOPE_DOUBLE)
893 {
894 // Truncate all triple indirect pages.
895 eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS);
896 if (eErrCode != store_E_None)
897 return eErrCode;
898
899 // Truncate double indirect pages, downto 'aLink.m_nIndex2'.
900 eErrCode = truncate (eScope, aLink.m_nIndex2 + 1, rBIOS);
901 if (eErrCode != store_E_None)
902 return eErrCode;
903
904 // Truncate last double indirect page to ... pages.
905 eErrCode = store_truncate_Impl (
906 doubleLink (aLink.m_nIndex2), aLink.m_nIndex1, aLink.m_nIndex0, rBIOS);
907 if (eErrCode != store_E_None)
908 return eErrCode;
909
910 // Check for complete truncation.
911 if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
912 {
913 // Clear pointer to last double indirect page.
914 doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL);
915 }
916 }
917 else if (eScope == page::SCOPE_TRIPLE)
918 {
919 // Truncate triple indirect pages, downto 'aLink.m_nIndex3'.
920 eErrCode = truncate (eScope, aLink.m_nIndex3 + 1, rBIOS);
921 if (eErrCode != store_E_None)
922 return eErrCode;
923
924 // Truncate last triple indirect page to ... pages.
925 eErrCode = store_truncate_Impl (
926 tripleLink (aLink.m_nIndex3), aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rBIOS);
927 if (eErrCode != store_E_None)
928 return eErrCode;
929
930 // Check for complete truncation.
931 if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0)
932 {
933 // Clear pointer to last triple indirect page.
934 tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL);
935 }
936 }
937 else if (eScope == page::SCOPE_UNREACHABLE)
938 {
939 // Out of scope.
940 eErrCode = store_E_CantSeek;
941 }
942 else
943 {
944 // Unknown scope.
945 SAL_WARN("store", "OStoreDirectoryPageObject::put(): scope failed");
946 eErrCode = store_E_Unknown;
947 }
948
949 // Leave.
950 return eErrCode;
951}
952
953/*
954 * truncate (external data page scope; private).
955 */
957 page::ChunkScope eScope,
958 sal_uInt16 nRemain,
959 OStorePageBIOS &rBIOS)
960{
961 // Enter.
962 storeError eErrCode = store_E_None;
963 if (eScope == page::SCOPE_DIRECT)
964 {
965 // Truncate direct data pages.
966 for (sal_uInt16 i = OStoreDirectoryDataBlock::directCount; i > nRemain; i--)
967 {
968 // Obtain data page location.
969 sal_uInt32 nAddr = directLink (i - 1);
970 if (nAddr == STORE_PAGE_NULL) continue;
971
972 // Free data page.
973 eErrCode = rBIOS.free (nAddr);
974 if (eErrCode != store_E_None)
975 break;
976
977 // Clear pointer to data page.
979 }
980
981 // Done.
982 return eErrCode;
983 }
984
985 if (eScope == page::SCOPE_SINGLE)
986 {
987 // Truncate single indirect pages.
988 for (sal_uInt16 i = OStoreDirectoryDataBlock::singleCount; i > nRemain; i--)
989 {
990 // Truncate single indirect page to zero data pages.
991 eErrCode = store_truncate_Impl (singleLink (i - 1), 0, rBIOS);
992 if (eErrCode != store_E_None)
993 break;
994
995 // Clear pointer to single indirect page.
997 }
998
999 // Done.
1000 return eErrCode;
1001 }
1002
1003 if (eScope == page::SCOPE_DOUBLE)
1004 {
1005 // Truncate double indirect pages.
1006 for (sal_uInt16 i = OStoreDirectoryDataBlock::doubleCount; i > nRemain; i--)
1007 {
1008 // Truncate double indirect page to zero single indirect pages.
1009 eErrCode = store_truncate_Impl (doubleLink (i - 1), 0, 0, rBIOS);
1010 if (eErrCode != store_E_None)
1011 break;
1012
1013 // Clear pointer to double indirect page.
1015 }
1016
1017 // Done.
1018 return eErrCode;
1019 }
1020
1021 if (eScope == page::SCOPE_TRIPLE)
1022 {
1023 // Truncate triple indirect pages.
1024 for (sal_uInt16 i = OStoreDirectoryDataBlock::tripleCount; i > nRemain; i--)
1025 {
1026 // Truncate to zero double indirect pages.
1027 eErrCode = store_truncate_Impl (tripleLink (i - 1), 0, 0, 0, rBIOS);
1028 if (eErrCode != store_E_None)
1029 break;
1030
1031 // Clear pointer to triple indirect page.
1033 }
1034
1035 // Done.
1036 return eErrCode;
1037 }
1038
1039 // Invalid scope.
1040 return store_E_InvalidAccess;
1041}
1042
1043/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual storeError verify(sal_uInt32 nAddr) const override
Definition: stordata.cxx:36
page::ChunkScope scope(sal_uInt32 nPage, page::DataBlock::LinkDescriptor &rDescr) const
scope (external data page; private).
Definition: stordata.cxx:544
virtual storeError guard(sal_uInt32 nAddr) override
External representation.
Definition: stordata.cxx:533
storeError write(sal_uInt32 nPage, OStoreDataPageObject &rData, OStorePageBIOS &rBIOS)
write (external data page).
Definition: stordata.cxx:750
sal_uInt32 singleLink(sal_uInt16 nIndex) const
single indirect.
Definition: stordata.hxx:662
page & PAGE()
Representation.
Definition: stordata.hxx:719
virtual storeError verify(sal_uInt32 nAddr) const override
Definition: stordata.cxx:538
storeError read(sal_uInt32 nPage, OStoreDataPageObject &rData, OStorePageBIOS &rBIOS) const
read (external data page).
Definition: stordata.cxx:677
sal_uInt32 tripleLink(sal_uInt16 nIndex) const
triple indirect.
Definition: stordata.hxx:686
sal_uInt32 directLink(sal_uInt16 nIndex) const
direct.
Definition: stordata.hxx:650
storeError truncate(sal_uInt32 nPage, OStorePageBIOS &rBIOS)
truncate (external data page).
Definition: stordata.cxx:834
sal_uInt32 doubleLink(sal_uInt16 nIndex) const
double indirect.
Definition: stordata.hxx:674
storeError truncate(sal_uInt16 nSingle, OStorePageBIOS &rBIOS)
truncate (indirect data page).
Definition: stordata.cxx:382
virtual storeError guard(sal_uInt32 nAddr) override
Definition: stordata.cxx:173
virtual storeError verify(sal_uInt32 nAddr) const override
Definition: stordata.cxx:178
storeError loadOrCreate(sal_uInt32 nAddr, OStorePageBIOS &rBIOS)
External representation.
Definition: stordata.cxx:153
storeError read(sal_uInt16 nSingle, OStoreDataPageObject &rData, OStorePageBIOS &rBIOS) const
read (indirect data page).
Definition: stordata.cxx:183
storeError write(sal_uInt16 nSingle, OStoreDataPageObject &rData, OStorePageBIOS &rBIOS)
write (indirect data page).
Definition: stordata.cxx:273
rtl::Reference< PageData::Allocator > & allocator()
Definition: storbios.hxx:57
storeError saveObjectAt(OStorePageObject &rPage, sal_uInt32 nAddr)
Definition: storbios.cxx:822
storeError loadObjectAt(OStorePageObject &rPage, sal_uInt32 nAddr)
Page I/O.
Definition: storbios.cxx:781
storeError free(sal_uInt32 nAddr)
Definition: storbios.cxx:760
storeError allocate(OStorePageObject &rPage)
Definition: storbios.cxx:715
bool dirty() const
State.
Definition: storbase.hxx:586
sal_uInt32 location() const
Location.
Definition: storbase.hxx:601
std::shared_ptr< PageData > m_xPage
Representation.
Definition: storbase.hxx:546
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
int nCount
sal_Int64 n
#define SAL_WARN(area, stream)
int i
Old OStorePageCache implementation.
Definition: lockbyte.cxx:133
sal_uInt32 htonl(sal_uInt32 h)
Definition: storbase.hxx:69
sal_uInt32 ntohl(sal_uInt32 n)
Definition: storbase.hxx:70
#define STORE_PAGE_NULL
Definition: storbase.hxx:114
static storeError store_truncate_Impl(sal_uInt32 nAddr, sal_uInt16 nSingle, OStorePageBIOS &rBIOS)
store_truncate_Impl (single indirect page).
Definition: stordata.cxx:44
static const sal_uInt16 singleCount
single.
Definition: stordata.hxx:428
static const sal_uInt16 directCount
direct.
Definition: stordata.hxx:411
static const sal_uInt16 tripleCount
triple.
Definition: stordata.hxx:462
static const sal_uInt16 doubleCount
double.
Definition: stordata.hxx:445
sal_uInt16 capacityCount() const
Definition: stordata.hxx:154
storeError
Error Code enumeration.
Definition: types.h:73
@ store_E_Unknown
Definition: types.h:95
@ store_E_None
Definition: types.h:74
@ store_E_InvalidAccess
Definition: types.h:80
@ store_E_CantSeek
Definition: types.h:77
@ store_E_NotExists
Definition: types.h:85
@ store_E_InvalidChecksum
Definition: types.h:83
@ store_E_Pending
Definition: types.h:92