summaryrefslogtreecommitdiff
path: root/store/source/storbios.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'store/source/storbios.cxx')
-rw-r--r--store/source/storbios.cxx863
1 files changed, 215 insertions, 648 deletions
diff --git a/store/source/storbios.cxx b/store/source/storbios.cxx
index 6f1a5cde0340..d2612d60b3db 100644
--- a/store/source/storbios.cxx
+++ b/store/source/storbios.cxx
@@ -83,36 +83,36 @@ struct OStoreSuperBlock
m_aUnused (0)
{}
- OStoreSuperBlock (const OStoreSuperBlock& rOther)
- : m_aGuard (rOther.m_aGuard),
- m_aDescr (rOther.m_aDescr),
- m_nMarked (rOther.m_nMarked),
- m_aMarked (rOther.m_aMarked),
- m_nUnused (rOther.m_nUnused),
- m_aUnused (rOther.m_aUnused)
+ OStoreSuperBlock (const OStoreSuperBlock & rhs)
+ : m_aGuard (rhs.m_aGuard),
+ m_aDescr (rhs.m_aDescr),
+ m_nMarked (rhs.m_nMarked),
+ m_aMarked (rhs.m_aMarked),
+ m_nUnused (rhs.m_nUnused),
+ m_aUnused (rhs.m_aUnused)
{}
- OStoreSuperBlock& operator= (const OStoreSuperBlock& rOther)
+ OStoreSuperBlock& operator= (const OStoreSuperBlock & rhs)
{
- m_aGuard = rOther.m_aGuard;
- m_aDescr = rOther.m_aDescr;
- m_nMarked = rOther.m_nMarked;
- m_aMarked = rOther.m_aMarked;
- m_nUnused = rOther.m_nUnused;
- m_aUnused = rOther.m_aUnused;
+ m_aGuard = rhs.m_aGuard;
+ m_aDescr = rhs.m_aDescr;
+ m_nMarked = rhs.m_nMarked;
+ m_aMarked = rhs.m_aMarked;
+ m_nUnused = rhs.m_nUnused;
+ m_aUnused = rhs.m_aUnused;
return *this;
}
/** Comparison.
*/
- sal_Bool operator== (const OStoreSuperBlock& rOther) const
+ sal_Bool operator== (const OStoreSuperBlock & rhs) const
{
- return ((m_aGuard == rOther.m_aGuard ) &&
- (m_aDescr == rOther.m_aDescr ) &&
- (m_nMarked == rOther.m_nMarked) &&
- (m_aMarked == rOther.m_aMarked) &&
- (m_nUnused == rOther.m_nUnused) &&
- (m_aUnused == rOther.m_aUnused) );
+ return ((m_aGuard == rhs.m_aGuard ) &&
+ (m_aDescr == rhs.m_aDescr ) &&
+ (m_nMarked == rhs.m_nMarked) &&
+ (m_aMarked == rhs.m_aMarked) &&
+ (m_nUnused == rhs.m_nUnused) &&
+ (m_aUnused == rhs.m_aUnused) );
}
/** unused(Count|Head|Insert|Remove|Reset).
@@ -173,94 +173,24 @@ struct OStoreSuperBlock
/*========================================================================
*
- * OStoreStateBlock.
- *
- *======================================================================*/
-struct OStoreStateBlock
-{
- enum StateBits
- {
- STATE_CLEAN = 0,
- STATE_CLOSE_WAIT = 1,
- STATE_FLUSH_WAIT = 2
- };
-
- /** Representation.
- */
- sal_uInt32 m_nState;
-
- /** theSize.
- */
- static const size_t theSize = sizeof(sal_uInt32);
-
- /** Construction.
- */
- OStoreStateBlock()
- : m_nState (store::htonl(STATE_CLEAN))
- {}
-
- /** Operation.
- */
- bool closePending (void) const
- {
- sal_uInt32 nState = store::ntohl(m_nState);
- return ((nState & STATE_CLOSE_WAIT) == STATE_CLOSE_WAIT);
- }
- void closed (void)
- {
- sal_uInt32 nState = store::ntohl(m_nState);
- nState &= ~STATE_CLOSE_WAIT;
- m_nState = store::htonl(nState);
- }
-
- bool flushPending (void) const
- {
- sal_uInt32 nState = store::ntohl(m_nState);
- return ((nState & STATE_FLUSH_WAIT) == STATE_FLUSH_WAIT);
- }
- void flushed (void)
- {
- sal_uInt32 nState = store::ntohl(m_nState);
- nState &= ~STATE_FLUSH_WAIT;
- m_nState = store::htonl(nState);
- }
-
- void modified (void)
- {
- sal_uInt32 nState = store::ntohl(m_nState);
- nState |= (STATE_CLOSE_WAIT | STATE_FLUSH_WAIT);
- m_nState = store::htonl(nState);
- }
- void clean (void)
- {
- sal_uInt32 nState = store::ntohl(m_nState);
- nState &= ~(STATE_CLOSE_WAIT | STATE_FLUSH_WAIT);
- m_nState = store::htonl(nState);
- }
-};
-
-/*========================================================================
- *
- * OStoreSuperBlockPage interface.
+ * SuperBlockPage interface.
*
*======================================================================*/
namespace store
{
-struct OStoreSuperBlockPage
+struct SuperBlockPage
{
typedef OStoreSuperBlock SuperBlock;
- typedef OStoreStateBlock StateBlock;
/** Representation.
*/
SuperBlock m_aSuperOne;
SuperBlock m_aSuperTwo;
- StateBlock m_aState;
/** theSize.
*/
- static const size_t theSize = 2 * SuperBlock::theSize + StateBlock::theSize;
+ static const size_t theSize = 2 * SuperBlock::theSize;
static const sal_uInt16 thePageSize = theSize;
STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
@@ -286,147 +216,138 @@ struct OStoreSuperBlockPage
/** Construction.
*/
- explicit OStoreSuperBlockPage (sal_uInt16 nPageSize = thePageSize)
+ explicit SuperBlockPage (sal_uInt16 nPageSize = thePageSize)
: m_aSuperOne(nPageSize),
- m_aSuperTwo(nPageSize),
- m_aState()
+ m_aSuperTwo(nPageSize)
{}
- /** guard (external representation).
- */
- void guard()
- {
- m_aSuperOne.guard();
- m_aSuperTwo.guard();
- }
-
/** save.
*/
- storeError save (OStorePageBIOS &rBIOS)
+ storeError save (OStorePageBIOS & rBIOS, sal_uInt32 nSize = theSize)
{
- // Guard.
- guard();
-
- // Write.
- return rBIOS.write (0, this, theSize);
+ m_aSuperOne.guard();
+ m_aSuperTwo = m_aSuperOne;
+ return rBIOS.write (0, this, nSize);
}
- /** close.
+ /** Page allocation.
*/
- storeError close (
- OStorePageBIOS &rBIOS);
+ storeError unusedHead (
+ OStorePageBIOS & rBIOS,
+ PageData & rPageHead);
- /** flush.
- */
- storeError flush (
- OStorePageBIOS &rBIOS);
+ storeError unusedPop (
+ OStorePageBIOS & rBIOS,
+ PageData const & rPageHead);
- /** modified.
- */
- storeError modified (
- OStorePageBIOS &rBIOS);
+ storeError unusedPush (
+ OStorePageBIOS & rBIOS,
+ sal_uInt32 nAddr);
/** verify (with repair).
*/
- storeError verify (
- OStorePageBIOS &rBIOS);
+ storeError verify (OStorePageBIOS & rBIOS);
};
} // namespace store
/*========================================================================
*
- * OStoreSuperBlockPage implementation.
+ * SuperBlockPage implementation.
*
*======================================================================*/
/*
- * close.
+ * unusedHead(): get freelist head (alloc page, step 1).
*/
-storeError OStoreSuperBlockPage::close (OStorePageBIOS &rBIOS)
+storeError SuperBlockPage::unusedHead (OStorePageBIOS & rBIOS, PageData & rPageHead)
{
- storeError eErrCode = store_E_None;
- if (m_aState.closePending())
+ storeError eErrCode = verify (rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ // Check freelist head.
+ OStorePageLink const aListHead (m_aSuperOne.unusedHead());
+ if (aListHead.location() == 0)
{
- // Mark as modified.
- m_aState.modified();
+ // Freelist empty, see SuperBlock::ctor().
+ rPageHead.location (STORE_PAGE_NULL);
+ return store_E_None;
+ }
- // Check access mode.
- if (rBIOS.isWriteable())
- {
- // Save StateBlock.
- StateBlock aState (m_aState);
+ // Load PageHead.
+ eErrCode = rBIOS.read (aListHead.location(), &rPageHead, PageData::theSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
- // Mark as clean.
- aState.clean();
+ eErrCode = rPageHead.verify (aListHead.location());
+ if (eErrCode != store_E_None)
+ return eErrCode;
- // Write behind SuperBlock.
- sal_uInt32 nAddr = 2 * SuperBlock::theSize;
- eErrCode = rBIOS.write (nAddr, &aState, StateBlock::theSize);
- }
+ // Verify page is unused.
+ sal_uInt32 const nAddr = rPageHead.m_aUnused.location();
+ OSL_POSTCOND(nAddr != STORE_PAGE_NULL, "store::SuperBlock::unusedHead(): page not free");
+ if (nAddr == STORE_PAGE_NULL)
+ {
+ // Page in use.
+ rPageHead.location (STORE_PAGE_NULL);
- // Mark as clean.
- m_aState.clean();
+ // Recovery: Reset freelist to empty.
+ m_aSuperOne.unusedReset();
+ eErrCode = save (rBIOS);
}
return eErrCode;
}
/*
- * flush.
+ * unusedPop(): pop freelist head (alloc page, step 2).
*/
-storeError OStoreSuperBlockPage::flush (OStorePageBIOS &rBIOS)
+storeError SuperBlockPage::unusedPop (OStorePageBIOS & rBIOS, PageData const & rPageHead)
{
- storeError eErrCode = store_E_None;
- if (m_aState.flushPending())
- {
- // Check access mode.
- if (rBIOS.isWriteable())
- {
- // Save StateBlock.
- StateBlock aState (m_aState);
-
- // Mark as flushed.
- aState.flushed();
-
- // Write behind SuperBlock.
- sal_uInt32 nAddr = 2 * SuperBlock::theSize;
- eErrCode = rBIOS.write (nAddr, &aState, StateBlock::theSize);
- }
-
- // Mark as flushed.
- m_aState.flushed();
- }
- return eErrCode;
+ sal_uInt32 const nAddr = rPageHead.m_aUnused.location();
+ OSL_PRECOND(nAddr != STORE_PAGE_NULL, "store::SuperBlock::unusedPop(): page not free");
+ if (nAddr == STORE_PAGE_NULL)
+ return store_E_CantSeek;
+
+ // Pop from FreeList.
+ OStorePageLink const aListHead (nAddr);
+ m_aSuperOne.unusedRemove (aListHead);
+ return save (rBIOS);
}
/*
- * modified.
+ * unusedPush(): push new freelist head.
*/
-storeError OStoreSuperBlockPage::modified (OStorePageBIOS &rBIOS)
+storeError SuperBlockPage::unusedPush (OStorePageBIOS & rBIOS, sal_uInt32 nAddr)
{
- storeError eErrCode = store_E_None;
- if (!m_aState.flushPending())
- {
- // Mark as modified.
- m_aState.modified();
+ storeError eErrCode = verify (rBIOS);
+ if (eErrCode != store_E_None)
+ return eErrCode;
- // Check access mode.
- if (rBIOS.isWriteable())
- {
- // Save StateBlock.
- StateBlock aState (m_aState);
+ PageData aPageHead;
+ eErrCode = rBIOS.read (nAddr, &aPageHead, PageData::theSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
- // Write behind SuperBlock.
- sal_uInt32 nAddr = 2 * SuperBlock::theSize;
- eErrCode = rBIOS.write (nAddr, &aState, StateBlock::theSize);
- }
- }
- return eErrCode;
+ eErrCode = aPageHead.verify (nAddr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ aPageHead.m_aUnused = m_aSuperOne.unusedHead();
+ aPageHead.guard (nAddr);
+
+ eErrCode = rBIOS.write (nAddr, &aPageHead, PageData::theSize);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ OStorePageLink const aListHead (nAddr);
+ m_aSuperOne.unusedInsert(aListHead);
+ return save (rBIOS);
}
/*
* verify (with repair).
*/
-storeError OStoreSuperBlockPage::verify (OStorePageBIOS &rBIOS)
+storeError SuperBlockPage::verify (OStorePageBIOS & rBIOS)
{
// Verify 1st copy.
storeError eErrCode = m_aSuperOne.verify();
@@ -636,8 +557,7 @@ OStorePageBIOS::AceCache::destroy (OStorePageBIOS::Ace * ace)
OStorePageBIOS::OStorePageBIOS (void)
: m_xLockBytes (NULL),
m_pSuper (NULL),
- m_bModified (sal_False),
- m_bWriteable (sal_False)
+ m_bWriteable (false)
{
}
@@ -646,158 +566,63 @@ OStorePageBIOS::OStorePageBIOS (void)
*/
OStorePageBIOS::~OStorePageBIOS (void)
{
- OStorePageBIOS::close();
-}
-
-/*
- * verify (SuperBlock with repair).
- * Internal: Precond: initialized, exclusive access.
- */
-storeError OStorePageBIOS::verify (SuperPage *&rpSuper)
-{
- // Check SuperBlock page allocation.
- if (rpSuper == 0)
- {
- // Allocate.
- if ((rpSuper = new SuperPage()) == 0)
- return store_E_OutOfMemory;
-
- // Load (w/o verification).
- storeError eErrCode = read (0, rpSuper, SuperPage::theSize);
- if (eErrCode != store_E_None)
- {
- // Cleanup and fail.
- delete rpSuper, rpSuper = 0;
- return eErrCode;
- }
-
- // Check SuperBlock state.
- if (rpSuper->m_aState.closePending())
- OSL_TRACE("OStorePageBIOS::verify(): close pending.\n");
-
- if (rpSuper->m_aState.flushPending())
- OSL_TRACE("OStorePageBIOS::verify(): flush pending.\n");
- }
-
- // Verify SuperBlock page (with repair).
- return rpSuper->verify (*this);
-}
-
-/*
- * repair (SuperBlock).
- * Internal: Precond: initialized, exclusive access.
- */
-storeError OStorePageBIOS::repair (SuperPage *&rpSuper)
-{
- // Acquire Lock.
- storeError eErrCode = acquireLock (0, SuperPage::theSize);
- if (eErrCode != store_E_None)
- return eErrCode;
-
- // Verify SuperBlock page (with repair).
- eErrCode = verify (rpSuper);
- if (eErrCode != store_E_None)
- {
- // Failure.
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // ReleaseLock.
- return releaseLock (0, SuperPage::theSize);
+ cleanup_Impl();
}
/*
- * create (SuperBlock).
- * Internal: Precond: initialized, exclusive access.
+ * initialize.
+ * Precond: none.
*/
-storeError OStorePageBIOS::create (sal_uInt16 nPageSize)
+storeError OStorePageBIOS::initialize (
+ ILockBytes * pLockBytes,
+ storeAccessMode eAccessMode,
+ sal_uInt16 & rnPageSize)
{
- // Check (internal) precond.
- OSL_PRECOND(m_xLockBytes.is(), "store::PageBIOS::create(): contract violation");
-
- // Check PageSize.
- if ((STORE_MINIMUM_PAGESIZE > nPageSize) || (nPageSize > STORE_MAXIMUM_PAGESIZE))
- return store_E_InvalidParameter;
- nPageSize = ((nPageSize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1));
-
- // Acquire Lock.
- storeError eErrCode = acquireLock (0, nPageSize);
- if (eErrCode != store_E_None)
- return eErrCode;
-
- // Allocate SuperBlock page.
- delete m_pSuper, m_pSuper = 0;
- if ((m_pSuper = new(nPageSize) SuperPage(nPageSize)) == 0)
- {
- // Cleanup and fail.
- releaseLock (0, nPageSize);
- return store_E_OutOfMemory;
- }
- m_pSuper->guard();
+ // Acquire exclusive access.
+ osl::MutexGuard aGuard (m_aMutex);
- // Create initial page (w/ SuperBlock).
- eErrCode = m_xLockBytes->writeAt (0, m_pSuper, nPageSize);
+ // Initialize.
+ storeError eErrCode = initialize_Impl (pLockBytes, eAccessMode, rnPageSize);
if (eErrCode != store_E_None)
{
- // Cleanup and fail.
- releaseLock (0, nPageSize);
- return eErrCode;
+ // Cleanup.
+ cleanup_Impl();
}
-
-#ifdef STORE_FEATURE_COMMIT
- // Commit.
- eErrCode = m_xLockBytes->flush();
- OSL_POSTCOND(
- eErrCode == store_E_None,
- "OStorePageBIOS::create(): flush failed");
-#endif /* STORE_FEATURE_COMMIT */
-
- // Adjust modified state.
- m_bModified = (eErrCode != store_E_None);
-
- // Release Lock and finish.
- return releaseLock (0, nPageSize);
+ return eErrCode;
}
/*
- * initialize.
- * Precond: none.
+ * initialize_Impl.
+ * Internal: Precond: exclusive access.
*/
-storeError OStorePageBIOS::initialize (
+storeError OStorePageBIOS::initialize_Impl (
ILockBytes * pLockBytes,
storeAccessMode eAccessMode,
sal_uInt16 & rnPageSize)
{
- // Acquire exclusive access.
- osl::MutexGuard aGuard (m_aMutex);
-
- // Check arguments.
- storeError eErrCode = store_E_InvalidParameter;
- if (!pLockBytes)
- return eErrCode;
-
// Cleanup.
-#if 0 /* OLD */
- __STORE_DELETEZ (m_pAcl); /* @@@ */
-#endif /* OLD */
- delete m_pSuper, m_pSuper = 0;
+ cleanup_Impl();
// Initialize.
m_xLockBytes = pLockBytes;
- m_bModified = sal_False;
- m_bWriteable = (!(eAccessMode == store_AccessReadOnly));
+ if (!m_xLockBytes.is())
+ return store_E_InvalidParameter;
+ m_bWriteable = (eAccessMode != store_AccessReadOnly);
// Check access mode.
- if (eAccessMode == store_AccessReadOnly)
- {
- // Verify SuperBlock page.
- eErrCode = verify (m_pSuper);
- }
- else if (eAccessMode != store_AccessCreate)
+ storeError eErrCode = store_E_None;
+ if (eAccessMode != store_AccessCreate)
{
- // Verify (w/ repair) SuperBlock page.
- eErrCode = repair (m_pSuper);
+ // Load SuperBlock page.
+ if ((m_pSuper = new SuperBlockPage()) == 0)
+ return store_E_OutOfMemory;
+
+ eErrCode = read (0, m_pSuper, SuperBlockPage::theSize);
+ if (eErrCode == store_E_None)
+ {
+ // Verify SuperBlock page (with repair).
+ eErrCode = m_pSuper->verify (*this);
+ }
}
else
{
@@ -806,13 +631,6 @@ storeError OStorePageBIOS::initialize (
if (eErrCode != store_E_None)
return eErrCode;
-#ifdef STORE_FEATURE_COMMIT
- // Commit.
- eErrCode = m_xLockBytes->flush();
- if (eErrCode != store_E_None)
- return eErrCode;
-#endif /* STORE_FEATURE_COMMIT */
-
// Mark as not existing.
eErrCode = store_E_NotExists;
}
@@ -829,14 +647,18 @@ storeError OStorePageBIOS::initialize (
if (eAccessMode == store_AccessReadWrite)
return store_E_NotExists;
- // Create SuperBlock page.
- eErrCode = create (rnPageSize);
+ // Check PageSize.
+ if ((STORE_MINIMUM_PAGESIZE > rnPageSize) || (rnPageSize > STORE_MAXIMUM_PAGESIZE))
+ return store_E_InvalidParameter;
+ rnPageSize = ((rnPageSize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1));
+
+ // Create initial page (w/ SuperBlock).
+ if ((m_pSuper = new(rnPageSize) SuperBlockPage(rnPageSize)) == 0)
+ return store_E_OutOfMemory;
+ eErrCode = m_pSuper->save (*this, rnPageSize);
}
if (eErrCode == store_E_None)
{
- // Obtain modified state.
- m_bModified = m_pSuper->m_aState.flushPending();
-
// Obtain page size.
rnPageSize = store::ntohs(m_pSuper->m_aSuperOne.m_aDescr.m_nSize);
@@ -852,33 +674,35 @@ storeError OStorePageBIOS::initialize (
}
/*
- * acquireLock.
- * Low Level: Precond: initialized, exclusive access.
+ * cleanup_Impl.
+ * Internal: Precond: exclusive access.
*/
-storeError OStorePageBIOS::acquireLock (
- sal_uInt32 nAddr, sal_uInt32 nSize)
+void OStorePageBIOS::cleanup_Impl()
{
- // Check precond.
- if (!m_xLockBytes.is())
- return store_E_InvalidAccess;
+ // Check referer count.
+ if (m_ace_head.m_used > 0)
+ {
+ // Report remaining referer count.
+ OSL_TRACE("store::PageBIOS::cleanup_Impl(): referer count: %d\n", m_ace_head.m_used);
+ for (Ace * ace = m_ace_head.m_next; ace != &m_ace_head; ace = m_ace_head.m_next)
+ {
+ m_ace_head.m_used -= ace->m_used;
+ AceCache::get().destroy (ace);
+ }
+ OSL_ENSURE(m_ace_head.m_used == 0, "store::PageBIOS::cleanup_Impl(): logic error");
+ }
- // Acquire Lock.
- return m_xLockBytes->lockRange (nAddr, nSize);
-}
+ // Release SuperBlock page.
+ delete m_pSuper, m_pSuper = 0;
-/*
- * releaseLock.
- * Low Level: Precond: initialized, exclusive access.
- */
-storeError OStorePageBIOS::releaseLock (
- sal_uInt32 nAddr, sal_uInt32 nSize)
-{
- // Check precond.
- if (!m_xLockBytes.is())
- return store_E_InvalidAccess;
+ // Release PageCache.
+ m_xCache.clear();
+
+ // Release PageAllocator.
+ m_xAllocator.clear();
- // Release Lock.
- return m_xLockBytes->unlockRange (nAddr, nSize);
+ // Release LockBytes.
+ m_xLockBytes.clear();
}
/*
@@ -892,7 +716,7 @@ storeError OStorePageBIOS::read (
if (!m_xLockBytes.is())
return store_E_InvalidAccess;
- // Read Page.
+ // Read Data.
return m_xLockBytes->readAt (nAddr, pData, nSize);
}
@@ -909,18 +733,6 @@ storeError OStorePageBIOS::write (
if (!m_bWriteable)
return store_E_AccessViolation;
- // Check modified state.
- if (!m_bModified)
- {
- // Mark as modified.
- m_bModified = sal_True;
-
- // Mark SuperBlock modified.
- storeError eErrCode = m_pSuper->modified (*this);
- if (eErrCode != store_E_None)
- return eErrCode;
- }
-
// Write Data.
return m_xLockBytes->writeAt (nAddr, pData, nSize);
}
@@ -1026,160 +838,44 @@ storeError OStorePageBIOS::allocate (
if (!m_bWriteable)
return store_E_AccessViolation;
- // Acquire SuperBlock Lock.
- storeError eErrCode = acquireLock (0, SuperPage::theSize);
- if (eErrCode != store_E_None)
- return eErrCode;
-
- // Load SuperBlock and require good health.
- eErrCode = verify (m_pSuper);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // Check allocation.
+ // Check allocation type.
+ storeError eErrCode = store_E_None;
if (eAlloc != ALLOCATE_EOF)
{
- // Check FreeList.
- OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead());
- if (aListHead.location())
- {
- // Allocate from FreeList.
- OStorePageData aPageHead (OStorePageData::theSize);
- aPageHead.location (aListHead.location());
-
- // Load PageHead.
- eErrCode = peek (aPageHead);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // Verify FreeList head.
- OSL_PRECOND(
- aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL,
- "OStorePageBIOS::allocate(): page not free");
- if (aPageHead.m_aUnused.location() == STORE_PAGE_NULL)
- {
- // Recovery: Reset FreeList.
- m_pSuper->m_aSuperTwo.unusedReset();
- m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
-
- // Save SuperBlock page.
- eErrCode = m_pSuper->save (*this);
-
- // Release SuperBlock Lock.
- releaseLock (0, SuperPage::theSize);
-
- // Recovery: Allocate from EOF.
- if (eErrCode == store_E_None)
- return allocate (rPage, ALLOCATE_EOF);
- else
- return store_E_Unknown;
- }
-
- // Pop from FreeList.
- aListHead = aPageHead.m_aUnused.location();
- rPage.get()->m_aUnused = STORE_PAGE_NULL;
-
- // Save page at PageHead location.
- eErrCode = saveObjectAt_Impl (rPage, aPageHead.location());
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // Save SuperBlock page.
- m_pSuper->m_aSuperTwo.unusedRemove (aListHead);
- m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
-
- eErrCode = m_pSuper->save (*this);
- OSL_POSTCOND(
- eErrCode == store_E_None,
- "OStorePageBIOS::allocate(): SuperBlock save failed");
-
- // Release SuperBlock Lock and finish.
- return releaseLock (0, SuperPage::theSize);
- }
- }
-
- // Allocate from logical EOF. Determine physical EOF.
- sal_uInt32 nPhysLen = STORE_PAGE_NULL;
- eErrCode = m_xLockBytes->getSize (nPhysLen);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // Obtain logical EOF.
- OStorePageDescriptor aDescr (m_pSuper->m_aSuperTwo.m_aDescr);
- sal_uInt32 nLogLen = store::ntohl(aDescr.m_nAddr);
- if (nLogLen == 0)
- nLogLen = nPhysLen; /* backward compatibility */
+ // Try freelist head.
+ PageData aPageHead;
+ eErrCode = m_pSuper->unusedHead (*this, aPageHead);
+ if (eErrCode != store_E_None)
+ return eErrCode;
- if (!(nLogLen < nPhysLen))
- {
- // Check modified state.
- if (!m_bModified)
+ sal_uInt32 const nAddr = aPageHead.location();
+ if (nAddr != STORE_PAGE_NULL)
{
- // Mark modified.
- m_bModified = sal_True;
-
- // Mark SuperBlock modified.
- eErrCode = m_pSuper->modified (*this);
+ // Save page.
+ eErrCode = saveObjectAt_Impl (rPage, nAddr);
if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
return eErrCode;
- }
- }
-
- // Resize.
- sal_uInt32 nAlign = SAL_MIN (nPhysLen, STORE_MAXIMUM_PAGESIZE);
- nPhysLen = ((nPhysLen + nAlign) / nAlign) * nAlign;
- eErrCode = m_xLockBytes->setSize (nPhysLen);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
+ // Pop freelist head and finish.
+ return m_pSuper->unusedPop (*this, aPageHead);
}
}
- // Save page at logical EOF.
- eErrCode = saveObjectAt_Impl (rPage, nLogLen);
+ // Allocate from EOF. Determine current size.
+ sal_uInt32 nSize = STORE_PAGE_NULL;
+ eErrCode = m_xLockBytes->getSize (nSize);
if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
return eErrCode;
- }
-
- // Save SuperBlock page.
- nLogLen += store::ntohs(aDescr.m_nSize);
- aDescr.m_nAddr = store::htonl(nLogLen);
-
- m_pSuper->m_aSuperTwo.m_aDescr = aDescr;
- m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
- eErrCode = m_pSuper->save (*this);
- OSL_POSTCOND(
- eErrCode == store_E_None,
- "OStorePageBIOS::allocate(): SuperBlock save failed");
-
- // Release SuperBlock Lock and finish.
- return releaseLock (0, SuperPage::theSize);
+ // Save page at current EOF.
+ return saveObjectAt_Impl (rPage, nSize);
}
/*
* free.
* Precond: initialized, writeable.
*/
-storeError OStorePageBIOS::free (OStorePageData & /* rData */, sal_uInt32 nAddr)
+storeError OStorePageBIOS::free (sal_uInt32 nAddr)
{
// Acquire exclusive access.
osl::MutexGuard aGuard (m_aMutex);
@@ -1190,58 +886,11 @@ storeError OStorePageBIOS::free (OStorePageData & /* rData */, sal_uInt32 nAddr)
if (!m_bWriteable)
return store_E_AccessViolation;
- // Acquire SuperBlock Lock.
- storeError eErrCode = acquireLock (0, SuperPage::theSize);
- if (eErrCode != store_E_None)
- return eErrCode;
-
- // Load SuperBlock and require good health.
- eErrCode = verify (m_pSuper);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // Load PageHead.
- OStorePageData aPageHead(OStorePageData::theSize);
- aPageHead.location (nAddr);
-
- eErrCode = peek (aPageHead);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
// Invalidate cache.
(void) m_xCache->removePageAt (nAddr);
- // Push onto FreeList.
- OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead());
-
- aPageHead.m_aUnused.m_nAddr = aListHead.m_nAddr;
- aListHead.m_nAddr = aPageHead.m_aDescr.m_nAddr;
-
- // Save PageHead.
- eErrCode = poke (aPageHead);
- if (eErrCode != store_E_None)
- {
- releaseLock (0, SuperPage::theSize);
- return eErrCode;
- }
-
- // Save SuperBlock page.
- m_pSuper->m_aSuperTwo.unusedInsert (aListHead);
- m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo;
-
- eErrCode = m_pSuper->save (*this);
- OSL_POSTCOND(
- eErrCode == store_E_None,
- "OStorePageBIOS::free(): SuperBlock save failed");
-
- // Release SuperBlock Lock and finish.
- return releaseLock (0, SuperPage::theSize);
+ // Push onto freelist.
+ return m_pSuper->unusedPush (*this, nAddr);
}
/*
@@ -1333,57 +982,16 @@ storeError OStorePageBIOS::saveObjectAt_Impl (OStorePageObject & rPage, sal_uInt
* close.
* Precond: none.
*/
-storeError OStorePageBIOS::close (void)
+storeError OStorePageBIOS::close()
{
// Acquire exclusive access.
osl::MutexGuard aGuard (m_aMutex);
- // Check referer count.
- if (m_ace_head.m_used > 0)
- {
- // Report remaining referer count.
- OSL_TRACE("store::PageBIOS::close(): referer count: %d\n", m_ace_head.m_used);
-#if 1 /* NEW */
- for (Ace * ace = m_ace_head.m_next; ace != &m_ace_head; ace = m_ace_head.m_next)
- {
- m_ace_head.m_used -= ace->m_used;
- AceCache::get().destroy (ace);
- }
- OSL_ENSURE(m_ace_head.m_used == 0, "store::PageBIOS::close(): logic error");
-#endif /* NEW */
- }
-
- // Check SuperBlock page.
- storeError eErrCode = store_E_None;
- if (m_pSuper)
- {
- // Release SuperBlock page.
- eErrCode = m_pSuper->close (*this);
- delete m_pSuper, m_pSuper = 0;
- }
-
- // Release PageCache.
- m_xCache.clear();
-
- // Check LockBytes.
- if (m_xLockBytes.is())
- {
-#ifdef STORE_FEATURE_COMMIT
- // Commit.
- storeError result = m_xLockBytes->flush();
- if (eErrCode == store_E_None)
- {
- // Previous result(s) okay. Propagate next result.
- eErrCode = result;
- }
-#endif /* STORE_FEATURE_COMMIT */
-
- // Release LockBytes.
- m_xLockBytes.clear();
- }
+ // Cleanup.
+ cleanup_Impl();
// Done.
- return eErrCode;
+ return store_E_None;
}
/*
@@ -1399,27 +1007,8 @@ storeError OStorePageBIOS::flush (void)
if (!m_xLockBytes.is())
return store_E_InvalidAccess;
- // Check mode and state.
- storeError eErrCode = store_E_None;
- if (!(m_bWriteable && m_bModified))
- return eErrCode;
-
- // Flush SuperBlock page.
- eErrCode = m_pSuper->flush (*this);
-
- // Flush LockBytes.
- storeError result = m_xLockBytes->flush();
- if (eErrCode == store_E_None)
- {
- // Previous result(s) okay. Propagate next result.
- eErrCode = result;
- }
-
- // Adjust modified state.
- m_bModified = (eErrCode != store_E_None);
-
- // Done.
- return eErrCode;
+ // Flush LockBytes and finish.
+ return m_xLockBytes->flush();
}
/*
@@ -1462,7 +1051,7 @@ storeError OStorePageBIOS::scanBegin (
return store_E_InvalidAccess;
// Check SuperBlock page.
- storeError eErrCode = verify (m_pSuper);
+ storeError eErrCode = m_pSuper->verify (*this);
if (eErrCode != store_E_None)
{
// Damaged. Determine page size (NYI).
@@ -1472,7 +1061,8 @@ storeError OStorePageBIOS::scanBegin (
// Setup Context descriptor.
rCtx.m_aDescr = m_pSuper->m_aSuperOne.m_aDescr;
- rCtx.m_aDescr.m_nAddr = rCtx.m_aDescr.m_nSize; // @@@ ntoh @@@
+ rCtx.m_aDescr.m_nSize = store::ntohs(rCtx.m_aDescr.m_nSize);
+ rCtx.m_aDescr.m_nAddr = rCtx.m_aDescr.m_nSize;
// Setup Context size.
eErrCode = size (rCtx.m_nSize);
@@ -1498,17 +1088,22 @@ storeError OStorePageBIOS::scanNext (
return store_E_InvalidAccess;
// Setup PageHead.
- OStorePageData aPageHead (OStorePageData::theSize);
+ PageData aPageHead;
// Check context.
while (rCtx.isValid())
{
// Assign next location.
- aPageHead.location (rCtx.m_aDescr.m_nAddr);
+ sal_uInt32 nAddr = rCtx.m_aDescr.m_nAddr;
rCtx.m_aDescr.m_nAddr += rCtx.m_aDescr.m_nSize;
- // Load PageHead.
- storeError eErrCode = peek (aPageHead);
+ // Read PageHead.
+ storeError eErrCode = read (nAddr, &aPageHead, PageData::theSize);
+ if (eErrCode != store_E_None)
+ continue;
+
+ // Verify PageHead.
+ eErrCode = aPageHead.verify (nAddr);
if (eErrCode != store_E_None)
continue;
@@ -1521,7 +1116,7 @@ storeError OStorePageBIOS::scanNext (
continue;
// Load page.
- eErrCode = loadObjectAt_Impl (rPage, aPageHead.location());
+ eErrCode = loadObjectAt_Impl (rPage, nAddr);
if (eErrCode != store_E_None)
continue;
@@ -1532,31 +1127,3 @@ storeError OStorePageBIOS::scanNext (
// Done.
return store_E_CantSeek;
}
-
-/*
- * peek (PageHead).
- * Internal: Precond: initialized, readable, exclusive access.
- */
-storeError OStorePageBIOS::peek (OStorePageData &rData)
-{
- // Read PageHead.
- storeError eErrCode = read (rData.location(), &rData, OStorePageData::theSize);
- if (eErrCode != store_E_None)
- return eErrCode;
-
- // Verify PageHead.
- return rData.verify();
-}
-
-/*
- * poke (PageHead).
- * Internal: Precond: initialized, writeable, exclusive access.
- */
-storeError OStorePageBIOS::poke (OStorePageData &rData)
-{
- // Guard PageHead.
- rData.guard();
-
- // Write PageHead.
- return write (rData.location(), &rData, OStorePageData::theSize);
-}