Andreas:

Are you going to release a new version or do you want to wait. If not, I have to download the SRC and build. Just let me know the plan for these types of things and thanks for the quick turnaround.

-MA

Andreas Aardal Hanssen wrote:

On Tue, 23 Sep 2003, Andreas Aardal Hanssen wrote:


Hi, Michael :-).
On Tue, 23 Sep 2003, Michael Amster wrote:


something like this for each folder (note I have 744 folders and this
takes about 1s per folder - it also pins CPU at 100%):
001 LIST "" "INBOX/myfolder/%"



This little patch should make consecutive LIST requests it a bit faster:


Andy :-)

--- src/operator-list.cc        14 Sep 2003 08:21:28 -0000      1.2
+++ src/operator-list.cc        23 Sep 2003 21:01:03 -0000
@@ -59,14 +59,13 @@
using namespace Binc;

namespace {
-  const int DIR_SELECT      = 0x01;
-  const int DIR_MARKED      = 0x02;
-  const int DIR_NOINFERIORS = 0x04;
+  const time_t LIST_CACHE_TIMEOUT = 10;
}

//----------------------------------------------------------------------
ListOperator::ListOperator(void)
{
+  cacheTimeout = 0;
}

//----------------------------------------------------------------------
@@ -91,6 +90,7 @@
                                             Request &command)
{
  IO &com = IOFactory::getInstance().get(1);
+  IO &logger = IOFactory::getInstance().get(2);
  const char delim = depot.getDelimiter();

  // special case: if the mailbox argument is empty, then give a
@@ -112,68 +112,83 @@
  trim(ref, string(&delim, 1));

  // a map from mailbox name to flags
-  map<string, int> mailboxes;
+  map<string, unsigned int> mailboxes;

-  // read through all entries in depository.
-  for (Depot::iterator i = depot.begin("."); i != depot.end(); ++i) {
-    const string path = *i;
-    const string mpath = depot.filenameToMailbox(path);
-    Mailbox *m = 0;
-
-    // skip entries that are not identified as mailboxes
-    if ((m = depot.get(mpath)) == 0)
-      continue;
-
-    // convert file name to mailbox name. skip it if there is no
-    // corresponding mailbox name.
-    string tmp = toCanonMailbox(depot.filenameToMailbox(path));
-    trim(tmp, string(&delim, 1));
-    if (tmp == "") continue;
-    else {
-      // inherit flags that were already set for this mailbox.
-      int flags = DIR_SELECT;
-      if (m->isMarked(path)) flags |= DIR_MARKED;
-      if (mailboxes.find(tmp) != mailboxes.end()) flags |= mailboxes[tmp];
-      mailboxes[tmp] = flags;
-    }
-
-    // now add all superior mailboxes with no flags set if not
-    // added already.
-    string::size_type pos = tmp.rfind(delim);
-    while (pos != string::npos) {
-      tmp = tmp.substr(0, pos);
+  if (cacheTimeout == 0 || cacheTimeout < time(0) - LIST_CACHE_TIMEOUT) {
+    // read through all entries in depository.
+    for (Depot::iterator i = depot.begin("."); i != depot.end(); ++i) {
+      const string path = *i;
+      const string mpath = depot.filenameToMailbox(path);
+      Mailbox *m = 0;
+
+      // skip entries that are not identified as mailboxes
+      if ((m = depot.get(mpath)) == 0)
+       continue;
+
+      // convert file name to mailbox name. skip it if there is no
+      // corresponding mailbox name.
+      string tmp = toCanonMailbox(depot.filenameToMailbox(path));
      trim(tmp, string(&delim, 1));
+      if (tmp == "") continue;
+      else {
+       // inherit flags that were already set for this mailbox.
+       int flags = DIR_SELECT;
+       if (m->isMarked(path)) flags |= DIR_MARKED;
+       if (mailboxes.find(tmp) != mailboxes.end()) flags |= mailboxes[tmp];
+       mailboxes[tmp] = flags;
+      }

-      if (mailboxes.find(tmp) == mailboxes.end())
-       mailboxes[tmp] = 0;
-
-      pos = tmp.rfind(delim);
+      // now add all superior mailboxes with no flags set if not
+      // added already.
+      string::size_type pos = tmp.rfind(delim);
+      while (pos != string::npos) {
+       tmp = tmp.substr(0, pos);
+       trim(tmp, string(&delim, 1));
+
+       if (mailboxes.find(tmp) == mailboxes.end())
+         mailboxes[tmp] = 0;
+
+       pos = tmp.rfind(delim);
+      }
    }
-  }

-  // find leaf nodes O(N^2)
-  map<string, int>::iterator i;
-  for (i = mailboxes.begin(); i != mailboxes.end(); ++i) {
-    string mailbox = i->first;
-    mailbox += delim;
-
-    bool leaf = true;
-    map<string, int>::const_iterator j;
-    for (j = mailboxes.begin(); j != mailboxes.end(); ++j) {
-      string::size_type pos = j->first.rfind(delim);
-      if (pos == string::npos) continue;
-
-      string base = j->first.substr(0, pos + 1);
-
-      if (mailbox == base) {
-       leaf = false;
-       break;
+    // find leaf nodes O(N^2)
+    map<string, unsigned int>::iterator i;
+    for (i = mailboxes.begin(); i != mailboxes.end(); ++i) {
+      string mailbox = i->first;
+      mailbox += delim;
+
+      bool leaf = true;
+      map<string, unsigned int>::const_iterator j = mailboxes.begin();
+      for (; j != mailboxes.end(); ++j) {
+       string::size_type pos = j->first.rfind(delim);
+       if (pos == string::npos) continue;
+
+       string base = j->first.substr(0, pos + 1);
+
+       if (mailbox == base) {
+         leaf = false;
+         break;
+       }
+      }
+
+      if (leaf) {
+       unsigned int flags = i->second;
+       flags |= DIR_LEAF;
+       i->second = flags;
      }
    }
+
+    cache = mailboxes;
+    cacheTimeout = time(0);
+  } else {
+    mailboxes = cache;
+    cacheTimeout = time(0);
  }
-
+
  // finally, print all mailbox entries with flags.
-  for (i = mailboxes.begin(); i != mailboxes.end(); ++i) {
+  map<string, unsigned int>::iterator i = mailboxes.begin();
+  for (; i != mailboxes.end(); ++i) {
    if (ref == "" || ((ref.length() <= i->first.length())
                     && (i->first.substr(0, ref.length()) == ref)))
      if (regexMatch(i->first, regex) == 0) {
--- src/operators.h     18 Aug 2003 18:06:05 -0000      1.1.1.1
+++ src/operators.h     23 Sep 2003 21:01:03 -0000
@@ -201,6 +201,16 @@

//--------------------------------------------------------------------
class ListOperator : public Operator {
+ protected:
+ enum MailboxFlags {
+ DIR_SELECT = 0x01,
+ DIR_MARKED = 0x02,
+ DIR_NOINFERIORS = 0x04,
+ DIR_LEAF = 0x08
+ };
+
+ std::map<std::string, unsigned int> cache;
+ time_t cacheTimeout;
public:
ProcessResult process(Depot &, Request &);
virtual ParseResult parse(Request &) const;






Reply via email to