[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    Re: PATCH: kmheaders.cpp
From:       Don Sanders <sanders () kde ! org>
Date:       2001-04-16 13:33:23
[Download RAW message or body]

On Monday 16 April 2001 10:13, Michael Häckel wrote:
> On Monday, 16. April 2001 03:46, Don Sanders wrote:
> > Updated patch, saves a few more megabytes.
>
> To me it looks good. It need around 25% less time now.

If you want to see real speed try out the attached patch. Sam has 
reimplemented index files, 30000 message folder switched to 3x faster (than 
before the kmheaders patch, with everything compiled as release). No increase 
in memory use.

But note this patch has known bugs and we have done a lot of work in 
decreasing memory usage since then, unfortunately this has resulted in speed 
falling back to what it was originally but we'll work on trying to get the 
best of both worlds today.

The changes in this file do reimplement some fundamental KMail data 
structures. Back up all your data first, or try it on a test Mail directory.

> For switching from a big folder with 35000 messages to a small one the time
> even goes down from 64 seconds to 4 seconds with this patch here. I don't
> know why that was so slow before as switching to the folder is much faster.

Try turning off threading. We seem to be stressing linuxes malloc (ie,. 
memory management) heavily. I still have problems even after applying the 
patch.

BFN,
Don.

["speedup1" (text/x-c++)]

Index: kmfolder.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.cpp,v
retrieving revision 1.148
diff -p -u -w -r1.148 kmfolder.cpp
--- kmfolder.cpp	2001/04/10 09:14:37	1.148
+++ kmfolder.cpp	2001/04/15 14:22:05
@@ -18,6 +18,7 @@
 #include <qregexp.h>
 #include <kmessagebox.h>
 #include <kdebug.h>
+#include <kcursor.h>
 
 #include <stdio.h>
 #include <errno.h>
@@ -47,7 +48,7 @@
 #define INIT_MSGS 8
 
 // Current version of the table of contents (index) files
-#define INDEX_VERSION 1504
+#define INDEX_VERSION 1505
 
 // Regular expression to find the line that seperates messages in a mail
 // folder:
@@ -207,7 +208,6 @@ int KMFolder::open()
       emit statusMsg(str);
     }
     else mIndexStream = fopen(indexLocation(), "r+"); // index file
-
     if (!mIndexStream) rc = createIndexFromContents();
     else readIndex();
   }
@@ -279,8 +279,14 @@ void KMFolder::close(bool aForced)
 
   if (mAutoCreateIndex)
   {
-    if (mDirty) writeIndex();
-    else sync();
+	bool dirty = mDirty;
+	if(!dirty) {
+	    for (int i=0; !dirty && i<mMsgList.high(); i++) 
+		if (mMsgList[i])
+		    dirty = mMsgList[i]->dirty();
+	}
+	if(dirty) 
+	    writeIndex();
     writeConfig();
   }
 
@@ -698,7 +704,7 @@ int KMFolder::writeIndex()
   QString tempName;
   KMMsgBase* msgBase;
   int old_umask;
-  int i=0;
+    int i=0, len;
 
   if (mIndexStream) fclose(mIndexStream);
   old_umask = umask(077);
@@ -711,12 +717,14 @@ int KMFolder::writeIndex()
   if (!mIndexStream) return errno;
 
   fprintf(mIndexStream, "# KMail-Index V%d\n", INDEX_VERSION);
-
   mHeaderOffset = ftell(mIndexStream);
   for (i=0; i<mMsgList.high(); i++)
   {
     if (!(msgBase = mMsgList[i])) continue;
-    fprintf(mIndexStream, "%s\n", (const char*)msgBase->asIndexString());
+	len = msgBase->indexStringLength();
+	fwrite(&len,sizeof(len), 1, mIndexStream);
+	if(fwrite(msgBase->asIndexString(), len, 1, mIndexStream) != 1) 
+	    qDebug("Whoa! %s:%d", __FILE__, __LINE__);
   }
   if (fflush(mIndexStream) != 0) return errno;
   if (fclose(mIndexStream) != 0) return errno;
@@ -737,25 +745,38 @@ void KMFolder::setAutoCreateIndex(bool a
 
 
 //-----------------------------------------------------------------------------
-bool KMFolder::readIndexHeader()
+bool KMFolder::readIndexHeader(int *gv)
 {
   int indexVersion;
 
   assert(mIndexStream != NULL);
 
   fscanf(mIndexStream, "# KMail-Index V%d\n", &indexVersion);
-  if (indexVersion == 1503 && INDEX_VERSION == 1504)
-  {
-    kdDebug() << "Converting index file " << (const char*)indexLocation() << " to \
utf-8" << endl; +    if(gv)
+	*gv = indexVersion;
+    if (indexVersion < 1505 ) {
+	if(indexVersion == 1503 && INDEX_VERSION == 1504) {
+	    kdDebug() << "Converting old index file " << (const char*)indexLocation() << " \
to utf-8" << endl;  mConvertToUtf8 = TRUE;
   }
-  else if (indexVersion < INDEX_VERSION)
-  {
+	return TRUE;
+    } else if (indexVersion < INDEX_VERSION) {
     kdDebug() << "Index file " << (const char*)indexLocation() << " is out of date. \
Re-creating it." << endl;  createIndexFromContents();
     return FALSE;
+    } else if(indexVersion > INDEX_VERSION) {
+	kapp->setOverrideCursor(KCursor::arrowCursor());
+	int r = KMessageBox::questionYesNo(0,
+					i18n(
+					    "The mail index for '%1' is from an unknown version of KMail (%2).\n"
+					    "This index can be regenerated from your mail folder, but some\n"
+					    "information, including status flags, may be lost. Do you wish\n"
+					    "to downgrade your index file ?") .arg(name()) .arg(indexVersion) );
+	kapp->restoreOverrideCursor();
+	if (r == KMessageBox::Yes) 
+	    createIndexFromContents();
+	return FALSE;
   }
-
   return TRUE;
 }
 
@@ -763,14 +784,15 @@ bool KMFolder::readIndexHeader()
 //-----------------------------------------------------------------------------
 void KMFolder::readIndex()
 {
-  QCString line(MAX_LINE);
+    int buffer_len=0, len;
+    uchar *buffer = NULL;
   KMMsgInfo* mi;
-
   assert(mIndexStream != NULL);
   rewind(mIndexStream);
 
   mMsgList.clear();
-  if (!readIndexHeader()) return;
+    int version;
+    if (!readIndexHeader(&version)) return;
 
   mUnreadMsgs = 0;
   mDirty = FALSE;
@@ -779,11 +801,30 @@ void KMFolder::readIndex()
   mMsgList.clear();
   while (!feof(mIndexStream))
   {
+	mi = NULL;
+	if(version >= 1505) {
+	    if(!fread(&len, sizeof(len), 1, mIndexStream)) 
+		break;
+	    if(len) {
+		if(len > buffer_len)
+		    buffer = (uchar *)realloc(buffer, buffer_len = len);
+		if(!buffer || !fread(buffer, len, 1, mIndexStream)) 
+		    break;
+	    }
+	    mi = new KMMsgInfo(this);
+	    if(buffer)
+		mi->fromIndexString(buffer, len);
+	} else {
+	    QCString line(MAX_LINE);
     fgets(line.data(), MAX_LINE, mIndexStream);
     if (feof(mIndexStream)) break;
 
     mi = new KMMsgInfo(this);
-    mi->fromIndexString(line, mConvertToUtf8);
+	    mi->compat_fromOldIndexString(line, mConvertToUtf8);
+	}	   
+	if(!mi)
+	    break;
+
     if (mi->status() == KMMsgStatusDeleted)
     {
       delete mi;  // skip messages that are marked as deleted
@@ -806,7 +847,9 @@ void KMFolder::readIndex()
     }
     mMsgList.append(mi);
   }
-  if (mConvertToUtf8)
+    if(buffer)
+	free(buffer);
+    if( version < 1505 && mConvertToUtf8)
   {
     mConvertToUtf8 = FALSE;
     mDirty = TRUE;
@@ -1549,73 +1592,88 @@ int KMFolder::expunge()
 //-----------------------------------------------------------------------------
 int KMFolder::compact()
 {
-  KMFolder* tempFolder;
-  KMMessage* msg;
   QCString tempName;
   QString msgStr;
-  int openCount = mOpenCount;
-  int num, numStatus;
   int rc = 0;
+    int openCount = mOpenCount;
 
   if (!needsCompact)
     return 0;
   kdDebug() << "Compacting " << endl;
-  tempName = "." + name().local8Bit();
 
-  tempName += ".compacted";
-  unlink(path().local8Bit() + "/" + tempName);
-  tempFolder = new KMFolder(parent(), tempName);   //sven: we create it
-  if(tempFolder->create()) {
-    kdDebug() << "KMFolder::compact() Creating tempFolder failed!\n" << endl;
-    delete tempFolder;                             //sven: and we delete it
-    return 0;
-  }
-
-  quiet(TRUE);
-  tempFolder->open();
+    tempName = "." + name() + ".compacted";
+    mode_t old_umask = umask(077);
+    FILE *tmpfile = fopen(tempName, "w");
+    umask(old_umask);
+    if (!tmpfile) 
+	return errno;
   open();
 
-  for(num=1,numStatus=9; count() > 0; num++, numStatus--)
-  {
-    if (numStatus <= 0)
-    {
-      msgStr = i18n("Compacting folder: %1 messages done").arg(num);
+    KMMsgInfo* mi;
+    int msize, offs=0, msgs=0, folder_offset;
+    QCString mtext;
+    for(int idx = 0; idx < mMsgList.count(); idx++) {
+	if(!(msgs++ % 10)) {
+	    msgStr = i18n("Compacting folder: %1 messages done").arg(msgs);
       emit statusMsg(msgStr);
-      numStatus = 10;
     }
-
-    msg = getMsg(0);
-    if(msg)
-      rc = tempFolder->moveMsg(msg);
+	mi = (KMMsgInfo*)mMsgList[idx];
+	msize = mi->msgSize();
+	mtext.resize(msize+2);
+	folder_offset = mi->folderOffset();
+
+	//now we need to find the separator! grr...
+	for(int i = (folder_offset-2); i; i -= 20) {
+	    if(fseek(mStream, i, SEEK_SET) == -1) {
+		rc = errno;
+		break;
+	    }
+	    fread(mtext.data(), 20, 1, mStream);
+	    for(int i2 = 0; i2 < 20; i2++)
+		if(*(mtext.data()+i2) == '\n') {
+		    int size = folder_offset - (i + i2);
+		    if(fseek(mStream, i + i2, SEEK_SET) == -1 || 
+		       !fread(mtext.data(), size, 1, mStream) || !fwrite(mtext.data(), size, 1, \
tmpfile)) { +			rc = errno;
+			break;
+		    }
+		    offs += size;
+		    i = 0;
+		    break;
+		}
+	}
     if (rc)
+	    break;
+	
+	if(fseek(mStream, folder_offset, SEEK_SET) == -1 ||
+	   !fread(mtext.data(), msize, 1, mStream) || !fwrite(mtext.data(), msize, 1, \
tmpfile)) { +	    rc = errno;
       break;
-    tempFolder->unGetMsg(tempFolder->count() - 1);
   }
-  tempName = tempFolder->location();
-  tempFolder->close(TRUE);
-  close(TRUE);
-  mMsgList.clear(TRUE);
+	mi->setFolderOffset(offs);
+	offs += msize;
+    }
+    fclose(tmpfile);
 
+
   if (!rc) {
+	writeIndex();
+	close(TRUE);
     _rename(tempName, location());
-    _rename(tempFolder->indexLocation(), indexLocation());
   }
   else
   {
+	close();
     kdDebug() << "Error occurred while compacting" << endl;
     kdDebug() << "Compaction aborted." << endl;
   }
 
-  // Now really free all memory
-  delete tempFolder;                //sven: we delete it, not the manager
-
   if (openCount > 0)
   {
     open();
     mOpenCount = openCount;
   }
   quiet(FALSE);
-
   if (!mQuiet)
     emit changed();
   else
@@ -1626,36 +1684,6 @@ int KMFolder::compact()
 
 
 //-----------------------------------------------------------------------------
-int KMFolder::sync()
-{
-  KMMsgBasePtr mb;
-  unsigned long offset = mHeaderOffset;
-  int i, rc, recSize = KMMsgBase::indexStringLength()+1;
-  int high = mMsgList.high();
-
-  if (!mIndexStream) return 0;
-
-  for (rc=0,i=0; i<high; i++)
-  {
-    mb = mMsgList[i];
-    if (mb->dirty())
-    {
-      fseek(mIndexStream, offset, SEEK_SET);
-      fprintf(mIndexStream, "%s\n", (const char*)mb->asIndexString());
-      rc = errno;
-      if (rc) break;
-      mb->setDirty(FALSE);
-    }
-    offset += recSize;
-  }
-  fflush(mIndexStream);
-
-  mDirty = FALSE;
-  return rc;
-}
-
-
-//-----------------------------------------------------------------------------
 const char* KMFolder::type() const
 {
   if (mAcctList) return "In";
Index: kmfolder.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.h,v
retrieving revision 1.45
diff -p -u -w -r1.45 kmfolder.h
--- kmfolder.h	2001/04/09 15:53:34	1.45
+++ kmfolder.h	2001/04/15 14:22:05
@@ -187,10 +187,6 @@ public:
     success. */
   virtual int expunge();
 
-  /** Sync all Index-changes to file. Returns zero on success and an errno
-    on failure. */
-  virtual int sync();
-
   /** Remove deleted messages from the folder. Returns zero on success
     and an errno on failure. */
   virtual int compact();
@@ -331,7 +327,7 @@ protected:
   virtual void readIndex();
 
   /** Read index header. Called from within readIndex(). */
-  virtual bool readIndexHeader();
+  virtual bool readIndexHeader(int *gv=NULL);
 
   /** Create index file from messages file and fill the message-info list
       mMsgList. Returns 0 on success and an errno value (see fopen) on
Index: kmmsgbase.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmsgbase.cpp,v
retrieving revision 1.69
diff -p -u -w -r1.69 kmmsgbase.cpp
--- kmmsgbase.cpp	2001/04/06 08:50:37	1.69
+++ kmmsgbase.cpp	2001/04/15 14:22:05
@@ -34,12 +34,18 @@ KMMsgBase::KMMsgBase(KMFolder* aParent)
   mFolderOffset = 0;
   mStatus  = KMMsgStatusNew;
   mDate    = 0;
+  mMsgIndex = NULL;
+  mMsgIndexSize = 0;
 }
 
 
 //-----------------------------------------------------------------------------
 KMMsgBase::~KMMsgBase()
 {
+    if(mMsgIndex) 
+	free(mMsgIndex);
+    mMsgIndex = NULL;
+    mMsgIndexSize = 0;
 }
 
 
@@ -52,6 +58,11 @@ void KMMsgBase::assign(const KMMsgBase* 
   mFolderOffset = other->mFolderOffset;
   mStatus = other->mStatus;
   mDate = other->mDate;
+
+  if(mMsgIndex)
+      free(mMsgIndex);
+  mMsgIndex = NULL;
+  mMsgIndexSize = 0;
 }
 
 
@@ -185,68 +196,6 @@ const QString KMMsgBase::dateStr(void) c
 
 
 //-----------------------------------------------------------------------------
-const QCString KMMsgBase::asIndexString(void) const
-{
-  int i, len;
-  QCString str; 
-  unsigned long dateTen = date();
-//  dateTen %= 10000000000; // In index only 10 chars are reserved for the date
-//  This is nonsense because 10000000000 is bigger than the highest unsigned
-//  long. (Or is there any compiler that defines unsigned long as something
-//  really huge?? )
-
-  QCString a(subject().utf8());
-  a.truncate(100);
-  QCString b(fromStrip().utf8());
-  b.truncate(50);
-  QCString c(toStrip().utf8());
-  c.truncate(47);
-  QCString d((const char*)replyToIdMD5());
-  d.truncate(22);
-  QCString e((const char*)msgIdMD5());
-  e.truncate(22);
-
-  // don't forget to change indexStringLength() below !!
-  str.sprintf("%c %-.9lu %-.9lu %-.10lu %-3.3s ",
-	      (char)status(), folderOffset(), msgSize(), dateTen,
-	      (const char*)xmark() );
-  if (str.length() != 37)
-    kdDebug() << "Invalid length " << endl;
-  str += a.rightJustify( 100, ' ' );
-  str += " ";
-  str += b.rightJustify( 50, ' ' );
-  str += " ";
-  str += c.rightJustify( 50, ' ' );
-  str += " ";
-  str += d.rightJustify( 22, ' ' );
-  str += " ";
-  str += e.rightJustify( 22, ' ' );
-
-  len = str.length();
-  for (i=0; i<len; i++)
-    if (str[i] < ' ' && str[i] >= 0)
-      str[i] = ' ';
-
-  if (str.length() != 285) {
-    kdDebug() << QString( "Error invalid index entry %1").arg(str.length()) << endl;
-    kdDebug() << str << endl;
-  }
-  return str;
-}
-
-
-//-----------------------------------------------------------------------------
-int KMMsgBase::indexStringLength(void)
-{
-  //return 237;
-  //  return 338; //sven (+ 100 chars to + one space, right?
-  //  return 339; //sanders (use 10 digits for the date we need this in 2001!)
-  //  return 541; //sanders include Reply-To and Message-Id for threading
-  return 285; // sanders strip from and to and use MD5 on Ids
-}
-
-
-//-----------------------------------------------------------------------------
 QString KMMsgBase::skipKeyword(const QString& aStr, char sepChar,
 				   bool* hasKeyword)
 {
@@ -701,4 +650,146 @@ const QString KMMsgBase::encodeBase64(co
   DwEncodeBase64(dwsrc, dwdest);
   result = dwdest.c_str();
   return result;
+}
+
+
+enum MsgPartType
+{
+    MsgNoPart = 0,
+    //unicode strings
+    MsgFromPart = 1, 
+    MsgSubjectPart = 2, 
+    MsgToPart = 3,
+    MsgReplyToIdMD5Part = 4,
+    MsgIdMD5Part = 5,
+    MsgXMarkPart = 6,
+    //unsigned long
+    MsgOffsetPart = 7,
+    MsgStatusPart = 8,
+    MsgSizePart = 9,
+    MsgDatePart = 10
+};
+
+//-----------------------------------------------------------------------------
+void KMMsgInfo::fromIndexString(const uchar *data, short data_len)
+{
+    //since we've loaded the old string is no good
+    if(mMsgIndex)
+	free(mMsgIndex);
+    mMsgIndex = NULL;
+    mMsgIndexSize = 0;
+
+    //now load
+    short offset = 0;
+#define COPY_DATA(x, length) do { \
+     if(offset + ((int)length) > data_len) {\
+        offset = data_len; \
+        qDebug("This should never happen.. %s:%d", __FILE__, __LINE__); \
+        memset(x, length, '\0'); \
+     } else { \
+        memcpy(x, data+offset, length); \
+	offset += length; \
+     } } while(0) 
+#define COPY_HEADER_TYPE(x) ASSERT(sizeof(x) == sizeof(MsgPartType)); COPY_DATA(&x, \
sizeof(x)) +#define COPY_HEADER_LEN(x)  ASSERT(sizeof(x) == sizeof(short)); \
COPY_DATA(&x, sizeof(x));  +#define SETUP_STRING(x) do { \
+     COPY_HEADER_LEN(l); \
+     if(offset + l > data_len) { \
+        offset = data_len; \
+        qDebug("This should never happen.. %s:%d", __FILE__, __LINE__); \
+	x = NULL; \
+     } else { \
+        x = QString((QChar *)(data + offset), l/2); \
+        offset += l; \
+     } } while(0)
+#define SETUP_INTEGER(x) do { COPY_HEADER_LEN(l); ASSERT(l == sizeof(x)); \
COPY_DATA(&x, sizeof(x)); } while(0) +    //with that out of the way, actual code..
+    MsgPartType type;
+    short l;
+    while(offset < data_len) {
+	COPY_HEADER_TYPE(type);
+	switch(type) {
+	default: 
+	    qDebug("Strange.. %d", type);
+	    break;
+	case MsgFromPart:
+	    SETUP_STRING(mFromStrip);
+	    break;
+	case MsgSubjectPart:
+	    SETUP_STRING(mSubject);
+	    break;
+	case MsgToPart:
+	    SETUP_STRING(mToStrip);
+	    break;
+	case MsgReplyToIdMD5Part:
+	    SETUP_STRING(mReplyToIdMD5);
+	    break;
+	case MsgIdMD5Part:
+	    SETUP_STRING(mMsgIdMD5);
+	    break;
+	case MsgXMarkPart:
+	    SETUP_STRING(mXMark);
+	    break;
+	case MsgOffsetPart:
+	    SETUP_INTEGER(mFolderOffset);
+	    break;
+	case MsgStatusPart:
+	    SETUP_INTEGER(mStatus);
+	    break;
+	case MsgSizePart:
+	    SETUP_INTEGER(mMsgSize);
+	    break;
+	case MsgDatePart:
+	    SETUP_INTEGER(mDate);
+	    break;
+	}
+    }
+#undef COPY_DATA
+    mDirty = FALSE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+const uchar *KMMsgBase::asIndexString(void)
+{
+    if(!dirty() && mMsgIndex) 
+	return mMsgIndex;
+    
+    if(mMsgIndex) {
+	free(mMsgIndex);
+	mMsgIndexSize = 0;
+    }
+    unsigned int csize = 256;
+    mMsgIndex = (uchar *)malloc(csize);
+#define STORE_DATA_LEN(type, x, len) do { \
+	if(csize < (mMsgIndexSize + (len + sizeof(short) + sizeof(MsgPartType)))) \
+    	   mMsgIndex = (uchar *)realloc(mMsgIndex, csize += QMAX(256, \
(len+sizeof(short)+sizeof(MsgPartType)))); \ +        MsgPartType t = type; \
memcpy(mMsgIndex+mMsgIndexSize, &t, sizeof(MsgPartType)); \ +        short l = len; \
memcpy(mMsgIndex+mMsgIndexSize+sizeof(MsgPartType), &l, sizeof(short)); \ +        \
memcpy(mMsgIndex+mMsgIndexSize+sizeof(short)+sizeof(MsgPartType), x, len); \ +        \
mMsgIndexSize += len + sizeof(short) + sizeof(MsgPartType); \ +    } while(0)
+#define STORE_DATA(type, x) STORE_DATA_LEN(type, &x, sizeof(x))
+    STORE_DATA_LEN(MsgFromPart, fromStrip().unicode(), fromStrip().length() * 2);
+    STORE_DATA_LEN(MsgSubjectPart, subject().unicode(), subject().length() * 2);
+    STORE_DATA_LEN(MsgToPart, toStrip().unicode(), toStrip().length() * 2);
+    STORE_DATA_LEN(MsgReplyToIdMD5Part, replyToIdMD5().unicode(), \
replyToIdMD5().length() * 2); +    STORE_DATA_LEN(MsgIdMD5Part, msgIdMD5().unicode(), \
msgIdMD5().length() * 2); +    STORE_DATA_LEN(MsgXMarkPart, xmark().unicode(), \
xmark().length() * 2); +    STORE_DATA(MsgStatusPart, mStatus);
+    STORE_DATA(MsgSizePart, mMsgSize);
+    STORE_DATA(MsgOffsetPart, mFolderOffset);
+    long tmp_l = date();
+    STORE_DATA(MsgDatePart, tmp_l);
+#undef STORE_DATA_LEN
+    return mMsgIndex;
+}
+
+
+//-----------------------------------------------------------------------------
+int KMMsgBase::indexStringLength(void)
+{
+    asIndexString(); //will change index size of needed
+    return mMsgIndexSize;
 }
Index: kmmsgbase.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmsgbase.h,v
retrieving revision 1.25
diff -p -u -w -r1.25 kmmsgbase.h
--- kmmsgbase.h	2001/04/05 20:19:09	1.25
+++ kmmsgbase.h	2001/04/15 14:22:05
@@ -82,20 +82,18 @@ public:
   virtual void setSubject(const QString&) = 0;
   virtual void setXMark(const QString&) = 0;
 
-  /** Return contents as index string. This string is of fixed size
-    that can be read with indexStringLength(). */
-  virtual const QCString asIndexString(void) const;
+    /** Return contents as index string. This string is of indexStringLength() size \
*/ +  const uchar *asIndexString(void);
+  /** Returns length of index strings returned by asIndexString(). */
+  int indexStringLength(void);
 
-  /** Returns fixed length of index strings returned by asIndexString(). */
-  static int indexStringLength(void);
-
   /** Get/set offset in mail folder. */
-  unsigned long folderOffset(void) const { return mFolderOffset; }
-  void setFolderOffset(unsigned long offs) { mFolderOffset=offs; }
+  virtual unsigned long folderOffset(void) const { return mFolderOffset; }
+  void setFolderOffset(unsigned long offs) { if(mFolderOffset != offs) { \
mFolderOffset=offs; setDirty(TRUE); } }  
   /** Get/set size of message including the whole header in bytes. */
-  unsigned long msgSize(void) const { return mMsgSize; }
-  void setMsgSize(unsigned long sz) { mMsgSize = sz; }
+  virtual unsigned long msgSize(void) const { return mMsgSize; }
+  void setMsgSize(unsigned long sz) { if(mMsgSize != sz) { mMsgSize = sz; \
setDirty(TRUE); } }  
   /** Skip leading keyword if keyword has given character at it's end
    * (e.g. ':' or ',') and skip the then following blanks (if any) too.
@@ -158,6 +156,12 @@ protected:
   time_t mDate;
   KMMsgStatus mStatus;
   bool mDirty;
+
+    int mMsgIndexSize;
+    uchar *mMsgIndex;
+
+private:
+    KMMsgBase( const KMMsgBase & ); //not implemented, don't use
 };
 
 typedef KMMsgBase* KMMsgBasePtr;
Index: kmmsginfo.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmsginfo.cpp,v
retrieving revision 1.24
diff -p -u -w -r1.24 kmmsginfo.cpp
--- kmmsginfo.cpp	2001/03/16 12:18:45	1.24
+++ kmmsginfo.cpp	2001/04/15 14:22:05
@@ -4,6 +4,7 @@
 #include "kmmessage.h"
 #include "kmmsgpart.h" // for encode
 
+#include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <assert.h>
@@ -96,7 +97,6 @@ const QString KMMsgInfo::toStrip(void) c
   return mToStrip;
 }
 
-
 //-----------------------------------------------------------------------------
 const QString KMMsgInfo::xmark(void) const
 {
@@ -121,37 +121,44 @@ const QString KMMsgInfo::msgIdMD5(void) 
 //-----------------------------------------------------------------------------
 void KMMsgInfo::setSubject(const QString& aSubject)
 {
-  mSubject = aSubject.copy();
+    if(mSubject != aSubject) {
+	mSubject = aSubject;
   mDirty = TRUE;
 }
+}
 
 
 //-----------------------------------------------------------------------------
 void KMMsgInfo::setXMark(const QString& aXMark)
 {
-  mXMark = aXMark.copy();
+    if(aXMark != mXMark) {
+	mXMark = aXMark;
   mDirty = TRUE;
 }
+}
 
 
 //-----------------------------------------------------------------------------
 void KMMsgInfo::setReplyToIdMD5(const QString& aReplyToIdMD5)
 {
-  mReplyToIdMD5 = aReplyToIdMD5.copy();
+    if(mReplyToIdMD5 != aReplyToIdMD5) {
+	mReplyToIdMD5 = aReplyToIdMD5;
   mDirty = TRUE;
 }
+}
 
 
 //-----------------------------------------------------------------------------
 void KMMsgInfo::setMsgIdMD5(const QString& aMsgIdMD5)
 {
-  mMsgIdMD5 = aMsgIdMD5.copy();
+    if(mMsgIdMD5 != aMsgIdMD5) {
+	mMsgIdMD5 = aMsgIdMD5;
   mDirty = TRUE;
 }
-
+}
 
-//-----------------------------------------------------------------------------
-void KMMsgInfo::fromIndexString(const QCString& str, bool toUtf8)
+//--- For compatability with old index files
+void KMMsgInfo::compat_fromOldIndexString(const QCString& str, bool toUtf8)
 {
   char *start, *offset;
 
Index: kmmsginfo.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmsginfo.h,v
retrieving revision 1.13
diff -p -u -w -r1.13 kmmsginfo.h
--- kmmsginfo.h	2001/03/16 12:18:45	1.13
+++ kmmsginfo.h	2001/04/15 14:22:05
@@ -18,7 +18,11 @@ public:
   virtual ~KMMsgInfo();
 
   /** Initialize from index string and set dirty flag to FALSE. */
-  virtual void fromIndexString(const QCString& str, bool toUtf8);
+  virtual void fromIndexString(const uchar *, short);
+
+    /* left for old style index files */
+    void compat_fromOldIndexString(const QCString& str, bool toUtf8);
+  
 
   /** Initialize with given values and set dirty flag to FALSE. */
   virtual void init(const QString& subject, const QString& from,


_______________________________________________
Kmail Developers mailing list
Kmail@master.kde.org
http://master.kde.org/mailman/listinfo/kmail


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic