ops, what a moron!  I forget to attach the patch.  Here it is (it's
again a two days old nightly build)
 
--
Joaqu�n Cuenca Abela
[EMAIL PROTECTED]
diff -ru --exclude=*akefile* abi/src/af/xap/xp/xad_Document.cpp abi-cached/src/af/xap/xp/xad_Document.cpp
--- abi/src/af/xap/xp/xad_Document.cpp	Wed Jun 13 12:01:25 2001
+++ abi-cached/src/af/xap/xp/xad_Document.cpp	Wed Jul  4 16:44:37 2001
@@ -45,7 +45,10 @@
 		char copy[1000];
 #endif
 		enumIgnores(i, &word);
+#ifdef DEBUG // silly, I know, but the compiler needs to know that the "copy" variable exists
+		// before optimizing it out.
 		UT_DEBUGMSG(("AD_Document::~AD_Document(), ignored spell word \"%s\"\n", UT_UCS_strcpy_to_char(copy, word)));
+#endif
 	}
 
    	// free all of the words on the list first
diff -ru --exclude=*akefile* abi/src/text/fmt/xp/fv_View.h abi-cached/src/text/fmt/xp/fv_View.h
--- abi/src/text/fmt/xp/fv_View.h	Thu Jun 28 12:01:36 2001
+++ abi-cached/src/text/fmt/xp/fv_View.h	Wed Jul  4 18:51:45 2001
@@ -530,9 +530,3 @@
 };
 
 #endif /* FV_VIEW_H */
-
-
-
-
-
-
diff -ru --exclude=*akefile* abi/src/text/ptbl/xp/pf_Frag.h abi-cached/src/text/ptbl/xp/pf_Frag.h
--- abi/src/text/ptbl/xp/pf_Frag.h	Thu Jun  7 12:01:43 2001
+++ abi-cached/src/text/ptbl/xp/pf_Frag.h	Wed Jul  4 10:58:28 2001
@@ -58,7 +58,7 @@
 	pt_PieceTable *			getPieceTable(void) { return m_pPieceTable;}
 	fd_Field *				getField(void);
 	PT_DocPosition          getPos(void) const { return m_docPos;}
-	void                    setPos(PT_DocPosition pos) { m_docPos = pos;}
+	void                    setPos(PT_DocPosition pos) const { m_docPos = pos;}
 	// createSpecialChangeRecord() constructs a change
 	// record which describes the fragment itself and
 	// not an actual change (editing) operation.  the
@@ -79,8 +79,9 @@
 	
     fd_Field *              m_pField;
 	pt_PieceTable *			m_pPieceTable;
+
 private:
-	PT_DocPosition          m_docPos;
+	mutable PT_DocPosition  m_docPos;
 };
 
 #endif /* PF_FRAG_H */
diff -ru --exclude=*akefile* abi/src/text/ptbl/xp/pf_Fragments.cpp abi-cached/src/text/ptbl/xp/pf_Fragments.cpp
--- abi/src/text/ptbl/xp/pf_Fragments.cpp	Wed Jun 27 12:01:32 2001
+++ abi-cached/src/text/ptbl/xp/pf_Fragments.cpp	Fri Jul  6 14:35:27 2001
@@ -26,9 +26,10 @@
 #include "ut_debugmsg.h"
 
 pf_Fragments::pf_Fragments()
-	: m_pFirst(NULL),
-	m_pLast(NULL),
-	m_bFragsClean(false)
+	: m_pFirst(0),
+	  m_pLast(0),
+	  m_pLastFragClean(0),
+	  m_pCache(0)
 {
 }
 
@@ -49,7 +50,6 @@
 	// append a frag to the end of the list
 	
 	UT_ASSERT(pf);
-	setFragsDirty();
 	if (!m_pLast)
 	{
 		UT_ASSERT(!m_pFirst);
@@ -67,15 +67,17 @@
 		m_pLast = pf;
 		pf->setNext(NULL);
 	}
+	setFragsDirty(pf);
+	
 	return;
 }
 
-pf_Frag * pf_Fragments::getFirst(void) const
+pf_Frag * pf_Fragments::getFirst() const
 {
 	return m_pFirst;
 }
 
-pf_Frag * pf_Fragments::getLast(void) const
+pf_Frag * pf_Fragments::getLast() const
 {
 	return m_pLast;
 }
@@ -83,7 +85,6 @@
 void pf_Fragments::insertFrag(pf_Frag * pfPlace, pf_Frag * pfNew)
 {
 	// insert the new fragment after the given fragment.
-	setFragsDirty();
 	UT_ASSERT(pfPlace);
 	UT_ASSERT(pfNew);
 
@@ -96,6 +97,7 @@
 	pfPlace->setNext(pfNew);
 	if (m_pLast == pfPlace)
 		m_pLast = pfNew;
+	setFragsDirty(pfNew);
 }
 
 void pf_Fragments::unlinkFrag(pf_Frag * pf)
@@ -103,12 +105,14 @@
 	// NOTE:  it is the caller's responsibility to delete pf if appropriate.
 	
 	UT_ASSERT(pf->getType() != pf_Frag::PFT_EndOfDoc);
-	setFragsDirty();
 	pf_Frag * pn = pf->getNext();
 	pf_Frag * pp = pf->getPrev();
 
 	if (pn)
+	{
 		pn->setPrev(pp);
+		setFragsDirty(pn);
+	}
 	if (pp)
 		pp->setNext(pn);
 
@@ -117,16 +121,22 @@
 
 	if (m_pLast == pf)
 		m_pLast = pp;
+	if (getCache() == pf)
+		setCache(pp);
 }
 
 /*!
  * This method clears out and repopulates the vectore of pointers to fragments.
  * It also sets the doc Positions of all the fragments.
  */
-void pf_Fragments::cleanFrags(void)
+void pf_Fragments::cleanFrags(pf_Frag* pFrom)
 {
-	if(m_vecFrags.getItemCount() > 0)
+	if (!pFrom) // pFrom is not yet used
+		pFrom = m_pFirst;
+
+	if (m_vecFrags.getItemCount() > 0)
 		m_vecFrags.clear();
+
 	pf_Frag * pfLast = NULL;
 	PT_DocPosition sum = 0;
 	for (pf_Frag * pf = getFirst(); (pf); pf=pf->getNext())
@@ -138,10 +148,10 @@
 	}
 	UT_ASSERT(pfLast && (pfLast->getType() == pf_Frag::PFT_EndOfDoc));
 	xxx_UT_DEBUGMSG(("SEVIOR: Found %d Frags dopos at end = %d \n",m_vecFrags.getItemCount(),getLast()->getPos()));
-	m_bFragsClean = true;
+	m_pLastFragClean = pfLast;
 }
 
-static void pf_fragments_clean_frags( void * p)
+static void pf_fragments_clean_frags(void * p)
 {
 	pf_Fragments * pFragments = static_cast<pf_Fragments *>(p);
 	pFragments->cleanFrags();
@@ -157,82 +167,114 @@
 
 pf_Frag * pf_Fragments::getNthFrag(UT_uint32 nthFrag) const
 {
-	if(areFragsDirty())
+	if (areFragsDirty())
 	{
+		xxx_UT_DEBUGMSG(("JCA: getNthFrag (%d): Cleanning fragments ( O(n) complexity! )\n", nthFrag));
 		cleanFragsConst();
 	}
-	if(m_vecFrags.getItemCount() > 0)
+	else
+		xxx_UT_DEBUGMSG(("JCA: getNthFrag (%d): Don't need to clean fragments\n", nthFrag));
+	
+	if (m_vecFrags.getItemCount() > 0)
 	{
+		xxx_UT_DEBUGMSG(("JCA: getNthFrag (%d): returning frag %p\n", nthFrag, m_vecFrags.getNthItem(nthFrag)));
 		return (pf_Frag *) m_vecFrags.getNthItem(nthFrag);
 	}
+
 	return NULL;
 }
 
 /*!
  * Binary search to find the first frag at position before pos
-\param PT_DocPosition we want to find for.
-\returns pf_Frag * pointer to the Frag with position immediately before pos
+ * @param PT_DocPosition we want to find for.
+ * @returns pf_Frag * pointer to the Frag with position immediately before pos
 */
-pf_Frag * pf_Fragments::findFirstFragBeforePos( PT_DocPosition pos) const
+pf_Frag * pf_Fragments::findFirstFragBeforePos(PT_DocPosition pos) const
 {
 	UT_uint32 numFrags = getNumberOfFrags();
-	if(numFrags  < 1)
+#ifdef DEBUG
+	UT_uint32 numIters = 0;
+#endif
+	xxx_UT_DEBUGMSG(("JCA: findFirstFragBeforePos (%d).  NbFrags = %d...\n", pos, numFrags));
+
+	if (numFrags  < 1)
 		return NULL;
-	if(pos >= getLast()->getPos())
+
+	if (pos >= getLast()->getPos())
 	{
-		xxx_UT_DEBUGMSG(("SEVIOR: Found last Frag= pos %d Looking for pos %d \n",getLast()->getPos(),pos));
+		xxx_UT_DEBUGMSG(("JCA: Found last Frag[%p] @ pos %d Looking for pos %d \n", getLast(), getLast()->getPos(), pos));
 		return getLast();
 	}
-	UT_sint32 diff = numFrags/2;
+
+	pf_Frag* cache = getCache();
+	if (cache && pos >= cache->getPos() && pos < cache->getPos() + cache->getLength())
+	{
+		xxx_UT_DEBUGMSG(("JCA: Value cached\n"));
+		return cache;
+	}
+	else
+		xxx_UT_DEBUGMSG(("JCA: Value not cached\n"));
+	
+	UT_sint32 diff = numFrags / 2;
 	UT_sint32 curFragNo = diff;
 	pf_Frag * curFrag = m_pLast;
 
-	while(diff > 1)
+	while (diff > 1)
 	{
+#ifdef DEBUG
+		++numIters;
+#endif
 		curFrag = (pf_Frag *) m_vecFrags.getNthItem(curFragNo);
-		if(pos < curFrag->getPos())
+		if (pos < curFrag->getPos())
 		{
-			diff = diff/2;
+			diff = diff / 2;
 			curFragNo -= diff;
 		}
 		else
 		{
-			diff = diff/2;
+			diff = diff / 2;
 			curFragNo += diff;
 		}
 	}
-	while( curFrag && pos > curFrag->getPos())
+	while (curFrag && pos > curFrag->getPos())
 	{
+#ifdef DEBUG
+		++numIters;
+#endif
 		curFrag = curFrag->getNext();
 	}
-	while( curFrag && pos < curFrag->getPos())
+	while (curFrag && pos < curFrag->getPos())
 	{
+#ifdef DEBUG
+		++numIters;
+#endif
 		curFrag = curFrag->getPrev();
 	}
-	xxx_UT_DEBUGMSG(("SEVIOR: Found at pos %d Looking for pos %d \n",curFrag->getPos(),pos));
-	if(curFrag && curFrag->getPrev() && curFrag->getNext())
+
+	xxx_UT_DEBUGMSG(("JCA: Found Frag[%p] at pos %d Looking for pos %d with [%d] iterations\n",
+				 curFrag, curFrag->getPos(), pos, numIters));
+	if (curFrag && curFrag->getPrev() && curFrag->getNext())
 	{
-		xxx_UT_DEBUGMSG(("SEVIOR Frag pos before = %d Frag Pos After %d Looking for pos %d \n",curFrag->getPrev()->getPos(),curFrag->getPos(),curFrag->getNext()->getPos(),pos));
+		xxx_UT_DEBUGMSG(("JCA: Frag pos before = %d Frag Pos After %d Looking for pos %d \n",
+						 curFrag->getPrev()->getPos(), curFrag->getPos(), curFrag->getNext()->getPos(), pos));
 	}
+	setCache(curFrag);
 	return curFrag;
 }
 
-UT_uint32 pf_Fragments::getFragNumber( const pf_Frag * pf) const
+UT_uint32 pf_Fragments::getFragNumber(const pf_Frag * pf) const
 {
-	if(areFragsDirty())
-	{
+	if (areFragsDirty())
 		cleanFragsConst();
-	}
-	return m_vecFrags.findItem( (void *) pf);
-}
 
+	return m_vecFrags.findItem((void *) pf);
+}
 
-UT_uint32 pf_Fragments::getNumberOfFrags(void) const
+UT_uint32 pf_Fragments::getNumberOfFrags() const
 {
-	if(areFragsDirty())
-	{
+	if (areFragsDirty())
 		cleanFragsConst();
-	}
+
 	return m_vecFrags.getItemCount();
 }
 
diff -ru --exclude=*akefile* abi/src/text/ptbl/xp/pf_Fragments.h abi-cached/src/text/ptbl/xp/pf_Fragments.h
--- abi/src/text/ptbl/xp/pf_Fragments.h	Thu Jun  7 12:01:44 2001
+++ abi-cached/src/text/ptbl/xp/pf_Fragments.h	Wed Jul  4 17:45:38 2001
@@ -44,29 +44,33 @@
 	void					appendFrag(pf_Frag * pf);
 	void					insertFrag(pf_Frag * pfPlace, pf_Frag * pfNew);
 	void					unlinkFrag(pf_Frag * pf);
-	void                    cleanFrags(void);
-	void                    cleanFragsConst(void) const;
-	pf_Frag *               getNthFrag( UT_uint32 nthFrag) const;
+	void                    cleanFrags(pf_Frag* pFrom = 0);
+	void                    cleanFragsConst() const;
+	pf_Frag *               getNthFrag(UT_uint32 nthFrag) const;
 	pf_Frag *               findFirstFragBeforePos(PT_DocPosition pos) const;
-	UT_uint32               getNumberOfFrags( void) const;
-	UT_uint32               getFragNumber( const pf_Frag * pf) const;
-	pf_Frag *				getFirst(void) const;
-	pf_Frag *				getLast(void) const;
-	void                    setFragsDirty(void) {m_bFragsClean = false;}
-	bool                    areFragsDirty( void) const { return !m_bFragsClean;}
+	UT_uint32               getNumberOfFrags() const;
+	UT_uint32               getFragNumber(const pf_Frag * pf) const;
+	pf_Frag *				getFirst() const;
+	pf_Frag *				getLast() const;
+	void                    setFragsDirty(pf_Frag* pFrom = 0) { pFrom ? m_pLastFragClean = pFrom : m_pLastFragClean = m_pFirst; }
+	bool                    areFragsDirty() const { return m_pLastFragClean != m_pLast; }
 
 #ifdef PT_TEST
 	void					__dump(FILE * fp) const;
 #endif
 	
-protected:
 private:
+	inline pf_Frag*			getCache() const { return m_pCache; }
+	inline void				setCache(pf_Frag* pf) const { m_pCache = pf; }
+
 	pf_Frag *				m_pFirst;
 	pf_Frag *				m_pLast;
 	UT_Vector               m_vecFrags;
-	bool                    m_bFragsClean;
-
-
+	pf_Frag *				m_pLastFragClean;
+	mutable pf_Frag*		m_pCache;
+#ifdef DEBUG
+	double					m_rStat; // % of lookups served by the cache
+#endif
 };
 
 #endif /* PF_FRAGMENTS_H */
diff -ru --exclude=*akefile* abi/src/text/ptbl/xp/pt_PieceTable.cpp abi-cached/src/text/ptbl/xp/pt_PieceTable.cpp
--- abi/src/text/ptbl/xp/pt_PieceTable.cpp	Wed Jun 27 12:01:34 2001
+++ abi-cached/src/text/ptbl/xp/pt_PieceTable.cpp	Wed Jul  4 17:50:22 2001
@@ -438,9 +438,11 @@
 //
 	pf_Frag * pfLast = m_fragments.findFirstFragBeforePos(docPos);
 
+	// why not just:
+	// UT_ASSERT(pfLast); *ppf = pfLast; if (pFragOffset) *pFragOffset = docPos - pfLast->getPos();
 	if(pfLast)
 	{
-		while(pfLast->getNext() && docPos >= pfLast->getPos()+pfLast->getLength())
+		while(pfLast->getNext() && docPos >= pfLast->getPos() + pfLast->getLength())
 		{
 			pfLast = pfLast->getNext();
 		}

Reply via email to