5 Replies Latest reply on Jan 5, 2011 12:26 PM by Galder Zamarreño

    the keyset() function

    omer zohar Newbie

      i was running a small test to see how eviction works. my goal is to have a cache of X items in memory, in LRU mode, and infinite number of entries evicted to back store (basically it is an in-memory LRU cache).

       

      here's my config file (grid-config.xml):

       

          <namedCache name="persistant">
            
              <clustering mode="distribution">
                <stateRetrieval timeout="60000" fetchInMemoryState="false"/>
                <sync/>
                <hash numOwners="2"/>
                <l1 enabled="true"/>
              </clustering>
              
              <loaders passivation="false" shared="true" preload="true">
                <loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="false" purgeOnStartup="false">
                  <properties>
                    <property name="location" value="${jboss.server.data.dir}${/}blackbox.cache"/>
                  </properties>
                </loader>
              </loaders>
              
              <eviction wakeUpInterval="600000" maxEntries="2" strategy="LRU"/>
              <expiration lifespan="86400000" maxIdle="-1"/>
            </namedCache>
      

       

       

      i ran the following code:

       

      EmbeddedCacheManager manager = new DefaultCacheManager("d:\\grid-config.xml" );
      Cache<String,String> data = manager.getCache("persistant");
              data.clear();
              
              System.out.println(data.getConfiguration().getEvictionStrategy().name());
              System.out.println(data.getConfiguration().getEvictionMaxEntries());
              data.put("b", "bb");
              data.put("a", "aa");
              data.put("c", "cc");
              data.put("d", "dd");
              
              System.out.println(data.keySet());
              
              Thread.sleep(1000);
              
              data.put("d", "dd");
              System.out.println(data.keySet());
              data.put("e", "ee");
              
              System.out.println(data.keySet());
              Thread.sleep(1000);
              System.out.println(data.size());
              
              for (String c : new String []{"a","b","c","d","e"}){
                  System.out.println(data.containsKey(c));
                  System.out.println(data.get(c));
                  
              }
      

       

      the result is:

       

       

      LRU
      2
      [c, d]
      [c, d]
      [d, e]
      2
      true
      aa
      true
      bb
      true
      cc
      true
      dd
      true
      ee
      
      

       

      i was wondering about the keyset() function. although it seems that all keys are present with the get/contains function, the keyset() returned is always the size of 2. my guess is this is what resides in memory?

      if that's the case when i ran 'data.get("a")', this means the data was pulled from the persistant store?

      is there a way that i can know when a get request was answered from memory and when it was from persistant?

        • 1. Re: the keyset() function
          Dave Marion Newbie

          A couple of thoughts:

           

          1. I believe that to get the desired cache store behavior that you describe you need to set passivation to true. This will allow entries to remain in the backing store when they are evicted from the cache.

          2. From your example, eviction has probably not occurred before the completion of your test program. Eviction wakeup interval is set to 5 minutes. After eviction occurs, you would probably only have two objects (d and e) in your cache.

          3. You may want to try the LIRS eviction strategy. I believe it acts like LRU (but the algorithm is different) and it may be faster.

          • 2. Re: the keyset() function
            omer zohar Newbie

            Dave Marion wrote:

             

            A couple of thoughts:

             

            1. I believe that to get the desired cache store behavior that you describe you need to set passivation to true. This will allow entries to remain in the backing store when they are evicted from the cache.

            2. From your example, eviction has probably not occurred before the completion of your test program. Eviction wakeup interval is set to 5 minutes. After eviction occurs, you would probably only have two objects (d and e) in your cache.

            3. You may want to try the LIRS eviction strategy. I believe it acts like LRU (but the algorithm is different) and it may be faster.

             

             

            i re-ran the test with <eviction wakeUpInterval="500" maxEntries="2" strategy="LRU"/>

            still, i get the same results, so i guess this isn't it.

             

            regarding passiviation, according to the docs:

             

            If true, data is only written to the cache store when it is evicted from memory, a phenomenon  known as 'passivation'. Next time the data is requested, it will be 'activated' which means  that data will be brought back to memory and removed from the persistent store. This gives you  the ability to 'overflow' to disk, similar to swapping in an operating system. 
             
             If false, the cache store contains a copy of the contents in memory, so writes to cache result  in cache store writes. This essentially gives you a 'write-through' configuration.
            

             

            So from what i understand, when passivation it true, the persistant is only in case of 'overflow' of the memory cache.

            what i need is a write-through mode, where all entries are immediately written to the persistatn as well as in memory for fast read.

            • 3. Re: the keyset() function
              Sanne Grinovero Master

              About the keySet() semantics I'm quoting the javadocs:

              http://docs.jboss.org/infinispan/4.2/apidocs/org/infinispan/Cache.html#keySet%28%29

              When this method is called on a cache configured with distribution mode, the set returned only contains the keys locally available in the cache instance. To avoid   memory issues, there will be not attempt to bring keys from other nodes. This method should only be used for debugging purposes such as to verify that the cache contains all the keys entered. Any other use involving execution of this method on a production system is not recommended.

               

              Regarding write-through, avoid using passivation and enable a cachestore: each put will immediately write to the store.

              1 of 1 people found this helpful
              • 4. Re: the keyset() function
                omer zohar Newbie

                thank you for your reply. this confirm my suspicion regarding the keyset () function.

                regarding write-through, i posted my cache settings in the first message. do you think this settings are correct for the uses i described? im not certain on the

                maxEntries="2"

                setting. in this case, they refer to max entries to be saved in memory? how can i control the number of enties in the store?

                • 5. Re: the keyset() function
                  Galder Zamarreño Master

                  There's no particular way of setting max number of entries in the store. However, if you set expiration, you can control the lifetime of cache entries both in memory and cache store (http://community.jboss.org/docs/DOC-14873#Expiration)