Funky replication message that might be an error message

One of our customers are experiencing some problems with some databases not replicating correctly. It might be connected to a recent upgrade to Domino 7.0.1 from 6.5.4 but we’re not sure. The problems can some times be fixed by clearing the replication history and manually replicating but that’s not really a long term solution.

To further troubleshoot I enabled the console log (set config console_log_enabled=1) and summary replication logging (set config log_replication=5) in the notes.ini via the Domino console. At the next scheduled replication I observed the strange messages (in bold below):

06-09-2006 10:49:35   Pushing dbname.nsf to servername/Organization dbname.nsf
06-09-2006 10:49:35   0 Bytes Saved from Field Level Replication
06-09-2006 10:49:35   0 Bytes Saved from Field Level Replication
06-09-2006 10:49:35   0 Bytes Saved from Field Level Replication
Unambiguous Note
NO Place Holders
Unambiguous Note
NO Place Holders
Unambiguous Note
NO Place Holders
Unambiguous Note
NO Place Holders
Unambiguous Note
NO Place Holders
06-09-2006 10:49:36   0 Bytes Saved from Field Level Replication
06-09-2006 10:49:36   0 Bytes Saved from Field Level Replication
06-09-2006 10:49:36   0 Bytes Saved from Field Level Replication
06-09-2006 10:49:36   0 Bytes Saved from Field Level Replication

I have never seen these messages before and it seems like they only appear with the databases we are having problems with.

If anyone has any information about these messages that they would be willing to share I would be a happy camper. I guess it’s also one of those times to be grateful that one can call Lotus Support!

Patch to Pebble 2.0-RC2 submitted

I have submitted a patch to Simon Brown (author of Pebble) to make it possible to handle additional filetypes using the core Pebble 2.0 framework. I have done it by modifying the net.sourceforge.pebble.domain.FileMetaData and moving the information about the possible filetypes to an enum (net.sourceforge.pebble.domain.TypeEnum). This enum may be subclassed in my application which is built upon Pebble to provide support for additional filetypes. I have used the enum from Jakarta Commons Lang because Java 5 enums doesn’t support subclassing.

The filetypes usable by the Pebble instance is configured using a factory (net.sourceforge.pebble.domain.TypeEnumFactory) which is instantiated and set in the net.sourceforge.pebble.Configuration object using the applicationContext-pebble.xml file. The actual bean set is configured from the included pebble_import_factories.xml file since I need to replace the factory easily from my build.xml. I also need to replace the FileDAOFactory so that bean definition has been moved to the xml-file as well.

The applicationContext-acegi-security.xml has been modified as well to import a bean instance from pebble_import_acegi.xml since I also need to be able to easily add something here from my build.

I have also added the possibility of specifying whether the individual filetypes may be managed and whether new directories may be added to the containing filetype directory by the user.

I have put the patch file itself on my blog for downloading. The patch should be applied to the Pebble 2.0-RC2 source tree.

Show ‘n Tell Thursday: Do you weigh in at Flyweight? (24 August 2006)


When working with a large number of (simple, similar) objects at once the amount of memory taken up by the objects can be considerable. Consider representing datapoints for a data series for a graph in objects. You might need to hold 2000 datapoints where many might be the same. Instead of wasting memory on a lot of identical objects you can use the Flyweight pattern.

In brief the pattern describes how to converve memory when working with a large number of objects by using a factory to construct objects rather than using the new keyword. By using the factory class you can do some checks before constructing a new object i.e. whether an existing object with the same properties already exists in a pool of already constructed objects. The example normally given, an the example used on Wikipedia, is that of representing a sentence where each letter is represented by an object. Using the Flyweight pattern a sentence will never use more than the 25 letter-objects (when talking ASCII) since there are no more than 25 unique letters. No need to represent each letter in the sentence as unique objects.

The sentence/letter example readily carries over to the graph example mentioned earlier.

Example

Let’s look at a simplified letter/sentence example in more detail. First the Letter class:

package com.lekkimworld.flyweight;

import java.util.HashMap;
import java.util.Map;

public class Letter {
   private static Map letters = new HashMap();
   private static int letter_count = 0;
   private char letter = 0;

   {
      // increment counter
      letter_count++;
   }

   public static Letter getInstance(char c) {
      Character c_obj = new Character(c);
      if (letters.containsKey(c_obj)) {
         // reuse existing object
         return (Letter)letters.get(c_obj);
      } else {
         // create new object
         Letter l = new Letter(c);
         letters.put(c_obj, l);
         return l;
      }
   }

   public static int getLetterCount() {
      return letter_count;
   }

   private Letter(char c) {
      this.letter = c;
   }

   public char getLetter() {
      return this.letter;
   }
}

…and then the Sentence class:

package com.lekkimworld.flyweight;

import java.util.LinkedList;
import java.util.List;

public class Sentence {
   private List letters = new LinkedList();

   public Sentence(String s) {
      for (int i=0; i<s.length(); i++) {
         letters.add(Letter.getInstance(s.charAt(i)));
      }
      System.out.println("Constructed sentence - used " + Letter.getLetterCount() +
            " instead of " + s.length() + " objects.");
   }

   public static void main(String[] args) {
      new Sentence("In the flyweight pattern, the data has no pointers " +
      	"to the data type methods, because these would consume too much space. " +
      	"Instead, the subroutines are called directly. In some cases, flyweight " +
      	"inheritance is performed by "shift-in" and "shift-out" data markers " +
      	"as a higher-level operation cycles through an array of flyweight data.");
   }

}

The output of running the example is as follows:

Constructed sentence - used 28 instead of 330 objects.

Here we saved creating 302 objects – imagine if we have been dealing with a long sentence how many object creations we could have spared the JVM and how much memory we saved. The central points are in bold in the Letter class and is the static getInstance (factory) method to create new objects, the private constructor and the Map to hold already created objects.

Conclusion

The Flyweight is a pattern that can save a lot of memory when you start representing everything as objects and the scenarios where it can be used are plentiful. I know the example is a bit simplistic but it demonstrates the point of the Flyweight pattern just fine. Don’t blame the pattern for the lack implementation in the example – blame me… 🙂

Will you weigh in at Flyweight the next time you need to handle many objects?

Further reading

While ideally suited for Java development due to the classes need to implement the pattern (static variables, a Map and normally a list of some kind) it should be possible in LotusScript – maybe using the collection classes from Johan. If you are interested the design patterns I highly suggest the Design Patterns book by GoF (Gang of Four).