summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--connectivity/source/drivers/dbase/DIndexIter.cxx6
-rw-r--r--connectivity/source/drivers/dbase/dindexnode.cxx58
-rw-r--r--connectivity/source/inc/dbase/dindexnode.hxx70
-rw-r--r--include/tools/ref.hxx13
-rw-r--r--tools/source/ref/ref.cxx10
5 files changed, 93 insertions, 64 deletions
diff --git a/connectivity/source/drivers/dbase/DIndexIter.cxx b/connectivity/source/drivers/dbase/DIndexIter.cxx
index b1c0a178bc29..edc3c995c9f5 100644
--- a/connectivity/source/drivers/dbase/DIndexIter.cxx
+++ b/connectivity/source/drivers/dbase/DIndexIter.cxx
@@ -52,7 +52,7 @@ sal_uIntPtr OIndexIterator::Find(bool bFirst)
if (bFirst)
{
m_aRoot = m_pIndex->getRoot();
- m_aCurLeaf = NULL;
+ m_aCurLeaf.Clear();
}
if (!m_pOperator)
@@ -186,7 +186,7 @@ sal_uIntPtr OIndexIterator::GetCompare(bool bFirst)
if ( ( ( pKey = GetNextKey() ) == NULL ) || !m_pOperator->operate(pKey,m_pOperand))
{
pKey = NULL;
- m_aCurLeaf = NULL;
+ m_aCurLeaf.Clear();
}
break;
case SQLFilterOperator::GREATER_EQUAL:
@@ -235,7 +235,7 @@ sal_uIntPtr OIndexIterator::GetNull(bool bFirst)
if ( ( ( pKey = GetNextKey() ) == NULL ) || !pKey->getValue().isNull())
{
pKey = NULL;
- m_aCurLeaf = NULL;
+ m_aCurLeaf.Clear();
}
return pKey ? pKey->GetRecord() : NODE_NOTFOUND;
}
diff --git a/connectivity/source/drivers/dbase/dindexnode.cxx b/connectivity/source/drivers/dbase/dindexnode.cxx
index 493ccd54f68e..fe206273db37 100644
--- a/connectivity/source/drivers/dbase/dindexnode.cxx
+++ b/connectivity/source/drivers/dbase/dindexnode.cxx
@@ -86,6 +86,15 @@ ONDXPage::~ONDXPage()
delete[] ppNodes;
}
+void ONDXPage::ReleaseRef()
+{
+ assert( nRefCount >= 1);
+ if(--nRefCount == 0 && !bNoDelete)
+ {
+ QueryDelete();
+ }
+}
+
void ONDXPage::QueryDelete()
{
// Store in GarbageCollector
@@ -105,14 +114,20 @@ void ONDXPage::QueryDelete()
ppNodes[i] = ONDXNode();
}
- RestoreNoDelete();
+ bNoDelete = 1;
nCount = 0;
aParent.Clear();
rIndex.Collect(this);
}
else
- SvRefBase::QueryDelete();
+ {
+ // I'm not sure about the original purpose of this line, but right now
+ // it serves the purpose that anything that attempts to do an AddFirstRef()
+ // after an object is deleted will trip an assert.
+ nRefCount = 1 << 30;
+ delete this;
+ }
}
ONDXPagePtr& ONDXPage::GetChild(ODbaseIndex* pIndex)
@@ -189,7 +204,7 @@ bool ONDXPage::Insert(ONDXNode& rNode, sal_uInt32 nRowsLeft)
{
// this practically reduces the number of nodes by 1
- if (IsLeaf() && this == &rIndex.m_aCurLeaf)
+ if (IsLeaf() && this == rIndex.m_aCurLeaf)
{
// assumes, that the node, for which the condition (<=) holds, is stored in m_nCurNode
--nCount; // (otherwise we might get Assertions and GPFs - 60593)
@@ -344,7 +359,7 @@ void ONDXPage::Release(bool bSave)
ppNodes[i].GetChild().Clear();
}
- aParent = NULL;
+ aParent.Clear();
}
void ONDXPage::ReleaseFull(bool bSave)
@@ -487,7 +502,7 @@ void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage)
sal_uInt16 nLastNode = bRight ? Count() - 1 : xPage->Count() - 1;
if (bRight)
{
- DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
+ DBG_ASSERT(xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
// shift all nodes from xPage to the left node (append)
while (xPage->Count())
{
@@ -497,7 +512,7 @@ void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage)
}
else
{
- DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
+ DBG_ASSERT(xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
// xPage is the left page and THIS the right one
while (xPage->Count())
{
@@ -520,7 +535,7 @@ void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage)
{
(*aParent)[0].SetChild();
aParent->ReleaseFull();
- aParent = NULL;
+ aParent.Clear();
rIndex.SetRootPos(nPagePos);
rIndex.m_aRoot = this;
SetModified(true);
@@ -567,7 +582,7 @@ void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage)
{
if (bRight)
{
- DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
+ DBG_ASSERT(xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
// Parent node will be integrated; is initialized with Child from xPage
(*aParent)[nParentNodePos].SetChild(xPage->GetChild(),aParent);
Append((*aParent)[nParentNodePos]);
@@ -576,7 +591,7 @@ void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage)
}
else
{
- DBG_ASSERT(&xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
+ DBG_ASSERT(xPage != this,"xPage und THIS duerfen nicht gleich sein: Endlosschleife");
// Parent-node will be integrated; is initialized with child
(*aParent)[nParentNodePos].SetChild(GetChild(),aParent); // Parent memorizes my child
Insert(0,(*aParent)[nParentNodePos]); // insert parent node into myself
@@ -601,7 +616,7 @@ void ONDXPage::Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage)
{
(*aParent).SetChild();
aParent->ReleaseFull();
- aParent = NULL;
+ aParent.Clear();
rIndex.SetRootPos(nPagePos);
rIndex.m_aRoot = this;
SetModified(true);
@@ -802,35 +817,24 @@ SvStream& connectivity::dbase::WriteONDXPagePtr(SvStream &rStream, const ONDXPag
ONDXPagePtr::ONDXPagePtr(const ONDXPagePtr& rRef)
- :ONDXPageRef(rRef)
+ :mpPage(rRef.mpPage)
,nPagePos(rRef.nPagePos)
{
+ if (mpPage != 0)
+ mpPage->AddNextRef();
}
ONDXPagePtr::ONDXPagePtr(ONDXPage* pRefPage)
- :ONDXPageRef(pRefPage)
+ :mpPage(pRefPage)
,nPagePos(0)
{
+ if (mpPage != 0)
+ mpPage->AddFirstRef();
if (pRefPage)
nPagePos = pRefPage->GetPagePos();
}
-ONDXPagePtr& ONDXPagePtr::operator=(const ONDXPagePtr& rRef)
-{
- ONDXPageRef::operator=(rRef);
- nPagePos = rRef.nPagePos;
- return *this;
-}
-
-
-ONDXPagePtr& ONDXPagePtr::operator= (ONDXPage* pRef)
-{
- ONDXPageRef::operator=(pRef);
- nPagePos = (pRef) ? pRef->GetPagePos() : 0;
- return *this;
-}
-
static sal_uInt32 nValue;
SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPage& rPage)
diff --git a/connectivity/source/inc/dbase/dindexnode.hxx b/connectivity/source/inc/dbase/dindexnode.hxx
index c59da5d299ed..791df0236efd 100644
--- a/connectivity/source/inc/dbase/dindexnode.hxx
+++ b/connectivity/source/inc/dbase/dindexnode.hxx
@@ -23,7 +23,6 @@
#include "file/FTable.hxx"
#include <connectivity/FValue.hxx>
#include <rtl/ref.hxx>
-#include <tools/ref.hxx>
#include <tools/stream.hxx>
#include <vector>
@@ -84,49 +83,53 @@ namespace connectivity
- // Index Page Pointer
-
class ONDXPage;
- typedef tools::SvRef<ONDXPage> ONDXPageRef; // Base class - because we need to store additional information
-
- class ONDXPagePtr : public ONDXPageRef
+ // Index Page Pointer
+ // This is ref-count pointer class
+ class ONDXPagePtr
{
friend SvStream& WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr&);
friend SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
+ ONDXPage* mpPage;
sal_uInt32 nPagePos; // Position in the index file
-
public:
- ONDXPagePtr(sal_uInt32 nPos = 0):nPagePos(nPos){}
+ ONDXPagePtr(sal_uInt32 nPos = 0) : mpPage(0), nPagePos(nPos) {}
ONDXPagePtr(const ONDXPagePtr& rRef);
ONDXPagePtr(ONDXPage* pRefPage);
-
- ONDXPagePtr& operator=(const ONDXPagePtr& rRef);
- ONDXPagePtr& operator=(ONDXPage* pPageRef);
+ inline ~ONDXPagePtr();
sal_uInt32 GetPagePos() const {return nPagePos;}
bool HasPage() const {return nPagePos != 0;}
- // sal_Bool Is() const { return isValid(); }
+
+ operator ONDXPage *() const { return mpPage; }
+ ONDXPage * operator ->() const { assert(mpPage != 0); return mpPage; }
+ bool Is() const { return mpPage != 0; }
+ inline void Clear();
};
// Index Page
-
- class ONDXPage : public SvRefBase
+ // This is a ref-counted class, with re-cycling
+ class ONDXPage
{
friend class ODbaseIndex;
+ friend class ONDXPagePtr;
friend SvStream& WriteONDXPage(SvStream &rStream, const ONDXPage&);
friend SvStream& operator >> (SvStream &rStream, ONDXPage&);
+ // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
+ unsigned int bNoDelete : 1;
+ unsigned int nRefCount : 31;
sal_uInt32 nPagePos; // Position in the index file
- bool bModified : 1;
+ bool bModified : 1;
sal_uInt16 nCount;
- ONDXPagePtr aParent, // Parent page
- aChild; // Pointer to the right child page
- ODbaseIndex& rIndex;
- ONDXNode* ppNodes; // Array of nodes
+ ONDXPagePtr aParent, // Parent page
+ aChild; // Pointer to the right child page
+ ODbaseIndex& rIndex;
+ ONDXNode* ppNodes; // Array of nodes
public:
// Node operations
@@ -174,9 +177,22 @@ namespace connectivity
protected:
ONDXPage(ODbaseIndex& rIndex, sal_uInt32 nPos, ONDXPage* = NULL);
- virtual ~ONDXPage();
-
- virtual void QueryDelete() SAL_OVERRIDE;
+ ~ONDXPage();
+
+ void ReleaseRef();
+ void QueryDelete();
+ void AddNextRef()
+ {
+ assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
+ ++nRefCount;
+ }
+ void AddFirstRef()
+ {
+ assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
+ if( bNoDelete )
+ bNoDelete = 0;
+ ++nRefCount;
+ }
void SetModified(bool bMod) {bModified = bMod;}
void SetPagePos(sal_uInt32 nPage) {nPagePos = nPage;}
@@ -189,6 +205,16 @@ namespace connectivity
#endif
};
+ inline ONDXPagePtr::~ONDXPagePtr() { if (mpPage != 0) mpPage->ReleaseRef(); }
+ inline void ONDXPagePtr::Clear()
+ {
+ if (mpPage != 0) {
+ ONDXPage * pRefObj = mpPage;
+ mpPage = 0;
+ pRefObj->ReleaseRef();
+ }
+ }
+
SvStream& WriteONDXPagePtr(SvStream &rStream, const ONDXPagePtr&);
SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
diff --git a/include/tools/ref.hxx b/include/tools/ref.hxx
index b18ce055081c..aecc2b379e00 100644
--- a/include/tools/ref.hxx
+++ b/include/tools/ref.hxx
@@ -26,6 +26,10 @@
#include <tools/toolsdllapi.h>
#include <vector>
+/**
+ This implements similar functionality to boost::intrusive_ptr
+*/
+
namespace tools {
/** T must be a class that extends SvRefBase */
@@ -152,7 +156,6 @@ class TOOLS_DLLPUBLIC SvRefBase
protected:
virtual ~SvRefBase();
- virtual void QueryDelete();
public:
SvRefBase() : bNoDelete(1), nRefCount(0) {}
@@ -183,7 +186,13 @@ public:
{
assert( nRefCount >= 1);
if( --nRefCount == 0 && !bNoDelete)
- QueryDelete();
+ {
+ // I'm not sure about the original purpose of this line, but right now
+ // it serves the purpose that anything that attempts to do an AddRef()
+ // after an object is deleted will trip an assert.
+ nRefCount = 1 << 30;
+ delete this;
+ }
}
unsigned int GetRefCount() const
diff --git a/tools/source/ref/ref.cxx b/tools/source/ref/ref.cxx
index 3a6aa59f1743..8be92d6547e8 100644
--- a/tools/source/ref/ref.cxx
+++ b/tools/source/ref/ref.cxx
@@ -23,14 +23,4 @@ SvRefBase::~SvRefBase()
{
}
-void SvRefBase::QueryDelete()
-{
- bNoDelete = 0;
- // I'm not sure about the original purpose of this line, but right now
- // it serves the purpose that anything that attempts to do an AddRef()
- // after an object is deleted will trip an assert.
- nRefCount = 1 << 30;
- delete this;
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */