summaryrefslogtreecommitdiff
path: root/sot/source/sdstor/stgcache.hxx
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2012-09-19 17:52:31 +0100
committerMichael Meeks <michael.meeks@suse.com>2012-09-19 17:53:49 +0100
commit1da4e8c6bf1f82691514edc5c780907b3009f443 (patch)
tree7bb300b708ba2835bec1499c7e19bcd403a6b406 /sot/source/sdstor/stgcache.hxx
parent3fa50ac35b6a56ae9628b0310cbf0eb7b4634736 (diff)
sot: stgcache re-factor to use sane lifecycle semantics
Store a dirty page hash to allow us to fix the LRU cache next. Change-Id: I67130af37ac1bc2d0a4abbb11f4d9871bb2bc306
Diffstat (limited to 'sot/source/sdstor/stgcache.hxx')
-rw-r--r--sot/source/sdstor/stgcache.hxx85
1 files changed, 53 insertions, 32 deletions
diff --git a/sot/source/sdstor/stgcache.hxx b/sot/source/sdstor/stgcache.hxx
index d556c5997590..268784683922 100644
--- a/sot/source/sdstor/stgcache.hxx
+++ b/sot/source/sdstor/stgcache.hxx
@@ -21,9 +21,11 @@
#define _STGCACHE_HXX
#include <osl/endian.h>
+#include <rtl/ref.hxx>
#include <tools/solar.h>
#include <tools/stream.hxx>
#include <stgelem.hxx>
+#include <boost/noncopyable.hpp>
#include <boost/unordered_map.hpp>
class UCBStorageStream;
@@ -34,7 +36,7 @@ class StorageBase;
typedef boost::unordered_map
<
sal_Int32,
- StgPage *,
+ rtl::Reference< StgPage >,
boost::hash< sal_Int32 >,
std::equal_to< sal_Int32 >
> IndexToStgPage;
@@ -43,12 +45,13 @@ class StgCache {
sal_uLong nError; // error code
sal_Int32 nPages; // size of data area in pages
sal_uInt16 nRef; // reference count
+ IndexToStgPage maDirtyPages; // hash of all dirty pages
IndexToStgPage maLRUCache; // hash of index to cached pages
short nPageSize; // page size of the file
UCBStorageStream* pStorageStream; // holds reference to UCB storage stream
- void Erase( StgPage* ); // delete a cache element
- StgPage* Create( sal_Int32 ); // create a cached page
+ void Erase( const rtl::Reference< StgPage >& ); // delete a cache element
+ rtl::Reference< StgPage > Create( sal_Int32 ); // create a cached page
protected:
SvStream* pStrm; // physical stream
sal_Bool bMyStream; // sal_True: delete stream in dtor
@@ -57,12 +60,12 @@ protected:
public:
StgCache();
~StgCache();
- void IncRef() { nRef++; }
+ void IncRef() { nRef++; }
sal_uInt16 DecRef() { return --nRef; }
void SetPhysPageSize( short );
sal_Int32 GetPhysPages() { return nPages; }
- short GetPhysPageSize() { return nPageSize; }
- SvStream* GetStrm() { return pStrm; }
+ short GetPhysPageSize() { return nPageSize; }
+ SvStream* GetStrm() { return pStrm; }
void SetStrm( SvStream*, sal_Bool );
void SetStrm( UCBStorageStream* );
sal_Bool IsWritable() { return ( pStrm && pStrm->IsWritable() ); }
@@ -74,47 +77,65 @@ public:
void ResetError();
sal_Bool Open( const String& rName, StreamMode );
void Close();
- sal_Bool Read( sal_Int32 nPage, void* pBuf, sal_Int32 nPages );
- sal_Bool Write( sal_Int32 nPage, void* pBuf, sal_Int32 nPages );
+ sal_Bool Read ( sal_Int32 nPage, void* pBuf, sal_Int32 nPages );
+ sal_Bool Write ( sal_Int32 nPage, void* pBuf, sal_Int32 nPages );
+
+ // two routines for accessing FAT pages
+ // Assume that the data is a FAT page and get/put FAT data.
+ void SetToPage ( const rtl::Reference< StgPage > xPage, short nOff, sal_Int32 nVal );
+ inline sal_Int32 GetFromPage ( const rtl::Reference< StgPage > xPage, short nOff );
+ void SetDirty ( const rtl::Reference< StgPage > &xPage );
sal_Bool SetSize( sal_Int32 nPages );
- StgPage* Find( sal_Int32 ); // find a cached page
- StgPage* Get( sal_Int32, sal_Bool ); // get a cached page
- StgPage* Copy( sal_Int32, sal_Int32=STG_FREE ); // copy a page
+ rtl::Reference< StgPage > Find( sal_Int32 ); // find a cached page
+ rtl::Reference< StgPage > Get( sal_Int32, sal_Bool ); // get a cached page
+ rtl::Reference< StgPage > Copy( sal_Int32, sal_Int32=STG_FREE ); // copy a page
sal_Bool Commit(); // flush all pages
void Clear(); // clear the cache
};
-class StgPage {
+class StgPage : public rtl::IReference, private boost::noncopyable {
+ sal_uInt32 mnRefCount;
const sal_Int32 mnPage; // page index
sal_uInt8* mpData; // nSize bytes
short mnSize; // size of this page
- bool mbDirty; // dirty flag
+ StgPage( short nData, sal_Int32 nPage );
+ virtual ~StgPage();
public:
- StgPage( short nData, sal_Int32 nPage );
- ~StgPage();
+ static rtl::Reference< StgPage > Create( short nData, sal_Int32 nPage );
- sal_Int32 GetPage() { return mnPage; }
- void* GetData() { return mpData; }
- short GetSize() { return mnSize; }
- bool IsDirty() { return mbDirty; }
- void SetDirty( bool bDirty ) { mbDirty = bDirty; }
- // routines for accessing FAT pages
- // Assume that the data is a FAT page and get/put FAT data.
- sal_Int32 GetPage( short nOff )
+ sal_Int32 GetPage() { return mnPage; }
+ void* GetData() { return mpData; }
+ short GetSize() { return mnSize; }
+
+public:
+ virtual oslInterlockedCount SAL_CALL acquire()
{
- if( ( nOff >= (short) ( mnSize / sizeof( sal_Int32 ) ) ) || nOff < 0 )
- return -1;
- sal_Int32 n = ((sal_Int32*) mpData )[ nOff ];
-#ifdef OSL_BIGENDIAN
- return OSL_SWAPDWORD(n);
-#else
- return n;
-#endif
+ return ++mnRefCount;
+ }
+ virtual oslInterlockedCount SAL_CALL release()
+ {
+ if ( --mnRefCount == 0)
+ {
+ delete this;
+ return 0;
+ }
+ return mnRefCount;
}
- void SetPage( short, sal_Int32 ); // put an element
static bool IsPageGreater( const StgPage *pA, const StgPage *pB );
};
+inline sal_Int32 StgCache::GetFromPage ( const rtl::Reference< StgPage > xPage, short nOff )
+{
+ if( ( nOff >= (short) ( xPage->GetSize() / sizeof( sal_Int32 ) ) ) || nOff < 0 )
+ return -1;
+ sal_Int32 n = ((sal_Int32*) xPage->GetData() )[ nOff ];
+#ifdef OSL_BIGENDIAN
+ return OSL_SWAPDWORD(n);
+#else
+ return n;
+#endif
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */