IBM®
Skip to main content
    Country/region select      Terms of use
 
 
   
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks  >  Lotus  >  Forums & community  >  Best Practice Makes Perfect

Best Practice Makes Perfect

A collaboration with Domino developers about how to do it and how to get it right in Domino

Occasionally one comes across a mail file containing hundreds of folders -- and in such cases, often many of them are empty.  The contents have been archived out, but there's no mechanism for finding unsued folders. Doing so manually is laborious -- so much so that most users don't bother to start. But if you're running up against some limit -- on the size of an outline, for instance -- it may be really necessary to locate and delete the empties.

Attached is an agent script to locate every empty folder in a mail file, and prompt the user which they would like to delete.

The key for finding folders efficiently, is the NotesNoteCollection.

Dim nnc As NotesNoteCollection
Set nnc = db.CreateNoteCollection(False)
nnc.SelectFolders = True
nnc.SelectionFormula = { !@Begins($TITLE; "(")  } ' skip Inbox and other system folders.
nnc.BuildCollection
strID = nnc.GetFirstNoteId
' build a list of folders that are candidates for deletion. We use a Note Collection to get the folders because it's
' a lot faster than iterating thru the db.views array.
Do While strID <> ""
       Set docDesignNote = db.GetDocumentByID(strID)
       strTitle = Strleft(docDesignNote.GetItemValue("$TITLE")(0) & "|", "|")

        Set view = db.GetView(strTitle)
...

if view.EntryCount = 0 Then
' record this folder as a deletion candidate.

...
       End If
       strID = nnc.GetNextNoteId(strID)
Loop

Why not just iterate through the db.Views array? Because (last I checked) when you get a Notes view object, the view index is updated. If you have less-used views in an application, it may take some time to do for all views when all you wanted was to check whether they were folders -- it also makes the views look like they are used when perhaps they aren't, frustrating efforts to identify unused views by flagging those whose indexes haven't been updated recently, as I've discussed in this blog. Unfortunately, there's no simple search for locating empty folders, so peeking into each folder is the only way to tell -- but that's still some bit faster.

Here's the full code: killEmpties.lss

Andre Guirard | 26 February 2008 03:17:00 AM ET | Caribou Coffee, Plymouth, MN, USA | Comments (8)


 Comments

1) Clean up empty folders
bob balaban | 2/26/2008 4:02:20 AM

Nice one. Minor point: In LotusScript, instead of testing for a null string with:

if s = "" ' or s <> ""

It's much faster to do it this way:

if len(s) = 0

2) Clean up empty folders
Charles Robinson | 2/26/2008 8:38:00 AM

"Why not just iterate through the db.Views array? Because (last I checked) when you get a Notes view object, the view index is updated."

Could this please be documented in the help? It's bewildering trying to track down all these random bits of knowledge that somehow became common knowledge even though I've never found them anywhere. :-)

@1 - That's another one that's good to know! It's a little weird that calling a function is faster than doing a compare. It would be interesting to know what LS is doing on the backend that makes it behave this way.

3) Clean up empty folders
Maria Helm | 2/26/2008 10:09:28 AM

"Doing so manually is laborious -- so much so that most users don't bother to start." The easy answer, if you want the user to do this on their own is (R7 & up):

1. Edit>Unread Marks>Mark all Unread

2. Look at the unread counts on folders. Does any folder NOT have a number beside it? If so, that folder is empty.

3. Expand all nested folders and repeat.

4. When done, Edit Unread Marks>Mark all Read.

Just offering an alternate solution for anyone who might find it useful.

But I acknowledge that there are definitely circumstances where running the code would be preferable.

4) re: Clean up empty folders
Andre Guirard | 2/26/2008 10:58:55 AM

Maria, good tip; thanks!

5) Clean up empty folders
Erik Brooks | 2/26/2008 12:18:30 PM

@2 - Just guessing from the computer science side of things... LS probably (like some other "memory-safe" languages) stores strings in two parts: A pointer or buffer to the string itself, and the current length of the string.

To get the length, the compiler can just read the "current length" portion from memory and go.

To compare the string against another it has to set up the comparing string, allocating memory, etc. and then iterate character-by-character through each to see if they match. A good compiler might check the length numbers first as a potential "easy way out", but there is still the setup cost, which involves asking the memory management for some temporary memory. And that's expensive.

6) Clean up empty folders
Charles Robinson | 2/26/2008 1:04:42 PM

@5 - I was a CS major so I know a bit about memory management. : -) As you said, checking the length before doing the comparison would make sense, and that's essentially what Bob is doing by using Len(). I expected the compiler or interpreter would apply that kind of short-circuit logic, and I was just wondering if someone currently or formerly with Lotus Software could comment on how it really works.

7) re: Clean up empty folders
Andre Guirard | 2/26/2008 1:50:35 PM

Charles, I did a timing test and will write up the results more formally this evening. Basically, the difference between them seems to be about the magnitude of a C function call. I'm guessing Len(x) where x is a defined string variable, can get translated by the compiler into a direct reference to the memory that stores the string length, whereas an = test calls a string compare function which starts to loop through the characters and immediately notices it's already out of characters on one side. There might also be some setup cost associated with the fact that string compares are complicated -- see Option Compare.

8) Ups.. client crash
Kim Andersen | 3/12/2008 6:19:18 AM

Nice script, but there is a problem. The deleted folders is removed, but the folders is not removed in the UI before the inbox is reloaded. If the user clicks on one of the deleted folders, the client crashes (R6.5.4).

9) Re: crash from clicking deleted folder
Andre Guirard | 3/12/2008 4:06:01 PM

Kim, good point. With version 8, there's an OutlineReload method that should probably be used to redisplay the outline without the deleted folders. In 6.x I guess you have to close the database.

 Add a Comment
Subject:
   
Name:
Comment:  (No HTML - Links will be converted if prefixed http://)
 
Remember Me?     Cancel

Search this blog 

Disclaimer 

    About IBM Privacy Contact