2 Replies Latest reply on Apr 2, 2006 6:20 PM by Elias Ross

    CacheLoader.get(Fqn name) return a view?

    Elias Ross Master

      I've been working on a cache loader for a B-Tree ODB called JDBM.

      I decided to store the keys as separate nodes. I think the way the Berkeley one is designed is that the entire subtree is loaded (all keys for a FQN) as a single Map object.

      Since I don't serialize as one big lump, the "get(Fqn)" method is sort of expensive, especially since it ends up loading all keys. Instead, I thought a "view" would be better. So this is what I came up with:

      class MapView extends AbstractMap {
      
       private Fqn name;
       private Set set;
      
       MapView(Fqn name) {
       this.name = name;
       }
      
       public Set entrySet() {
       if (set == null)
       set = new SetView(name);
       return set;
       }
      
       public Object get(Object key) {
       try {
       return nullUnmask(tree.find(key(name, key)));
       } catch (IOException e) {
       throw new RuntimeException(e);
       }
       }
      
       public boolean containsKey(Object key) {
       try {
       return exists(key(name, key));
       } catch (IOException e) {
       throw new RuntimeException(e);
       }
       }
      
       public Object put(Object key, Object value) {
       try {
       return JdbmCacheLoader.this.put(name, key, value);
       } catch (Exception e) {
       throw new RuntimeException(e);
       }
       }
      
       public Object remove(Object key) {
       try {
       return JdbmCacheLoader.this.remove(name, key);
       } catch (IOException e) {
       throw new RuntimeException(e);
       }
       }
      
       public int size() {
       return entrySet().size();
       }
      
       }
      


      Basically, the various Map operations become discrete calls in the underlying cache store. So, calling "CacheLoader.get(Fqn).get(key)" fetches a single value. Is this just premature optimization, or a genuine improvement?

      To me, it seems a bit strange that all entries for a node are loaded as a single Map. Is a single FQN's Map set a fairly compact entity, i.e. always able to be loaded in memory?


        • 1. Re: CacheLoader.get(Fqn name) return a view?
          Manik Surtani Master

          This depends on how people use maps in nodes, but in general I believe that the Map of a Node should be loaded and unloaded atomically. Simply because if we do try partial loading of this map, we will never know if the map is completely loaded (to perform operations such as getKeys() or numAttribs()) without maintaining a separate flag of sorts to tell us about partially loaded maps.

          I'm not saying it is a bad idea - on the contrary, lazy loading the contents of a node can only be a good thing. My only concern is that there will be a complexity and overhead penalty for doing this, and is this penalty worthwhile considering common use cases?

          • 2. Re: CacheLoader.get(Fqn name) return a view?
            Elias Ross Master


            Okay, I settled on returning a simple HashMap from the "get" operation. I'll rely on the fact that JBossCache won't call "get" for every key separately. I was very confused by the performance test which seemed to repeatedly do:

            CacheLoader.get(Fqn name).get(Object key)


            which isn't a very "fair" test, IMHO.

            Although I'm not going to write it as a "view", I decided to keep the keys as discrete entries, though. It doesn't seem to be a performance issue and can only improve cases where there are thousands of keys being changed or removed for a Fqn.