Implementing Cache

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Implementing Cache

Tutika Chakravarthy
Hi All,
I have seen the sample code to implement cache using
FutureTask and ConcuurentHashMap in one of the threads
in this mailing list :

code snippet :

public interface Computable<A, V> {
     V compute(A arg) throws Exception;
}

public class Memoize<A, V> implements Computable<A, V>
{
     public Memoize(Computable<A, V> c) {
         this.c = c;
     }
     public V compute(final A arg) throws Exception {
         Future<V> f = cache.get(arg);
         if (f == null) {
             Callable<V> eval = new Callable<V>() {
                 public V call() throws Exception {
                     return c.compute(arg);
                 }
             };
             FutureTask<V> ft = new
FutureTask<V>(eval);
             f = cache.putIfAbsent(arg, ft);
             if (f == null) { f = ft; ft.run(); }
         }
         return f.get();
     }
     private final ConcurrentMap<A, Future<V>> cache =
         new ConcurrentHashMap<A, Future<V>>();
     private final Computable<A, V> c;
}

 I would like to know how put method in Cache can be
 implemented using FutureTask .
 
 My put method will be put(key,value).
 
 I tried creating a dummy task with callable object
 which returns the value we passed to it  and  it
 worked fine.
 
 Is there any good way of implementing the put method?

 
 Tutika


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Implementing Cache

Joe Bowbeer
On 5/12/06, Tutika Chakravarthy <[hidden email]> wrote:
>  I would like to know how put method in Cache can be
>  implemented using FutureTask .
>

If you wanted to add a "put" method in order to seed the cache, you
might implement it as follows:

  public FutureTask<V> put(A arg, final V val) {
      Future<V> f = cache.get(arg);
      if (f == null) {
          Callable<V> eval = new Callable<V>() {
              public V call() {
                  return val;
              }
          };
          FutureTask<V> ft = new FutureTask<V>(eval);
          f = cache.putIfAbsent(arg, ft);
          if (f == null) {
              f = ft;
              ft.run();
          }
      }
      return f;
  }

Note that the FutureTask "trick" is useful when computing a new value
for the cache can take a long time.  If the computation time is not an
issue, however, then you can cache the raw values directly rather than
using a FutureTask (which can be thought of as a promise to produce a
value).

If you're using raw values, then your cache could be an instance of
ConcurrentHashMap and your API could be as simple as cache.get(key)
and cache.put(key, val).

Also, it might help you to know that the memo-cache example was
covered in the Bowbeer/Holmes talk at JavaOne 2005, and I believe it
was also covered in the Goetz/Holmes talk.  Both talks are viewable
online.

http://java.sun.com/javaone/sf/speaker_awards.jsp
 http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-3423.html
 http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-5807.html


On 5/12/06, Tutika Chakravarthy <[hidden email]> wrote:

> Hi All,
> I have seen the sample code to implement cache using
> FutureTask and ConcuurentHashMap in one of the threads
> in this mailing list :
>
> code snippet :
>
> public interface Computable<A, V> {
>      V compute(A arg) throws Exception;
> }
>
> public class Memoize<A, V> implements Computable<A, V>
> {
>      public Memoize(Computable<A, V> c) {
>          this.c = c;
>      }
>      public V compute(final A arg) throws Exception {
>          Future<V> f = cache.get(arg);
>          if (f == null) {
>              Callable<V> eval = new Callable<V>() {
>                  public V call() throws Exception {
>                      return c.compute(arg);
>                  }
>              };
>              FutureTask<V> ft = new
> FutureTask<V>(eval);
>              f = cache.putIfAbsent(arg, ft);
>              if (f == null) { f = ft; ft.run(); }
>          }
>          return f.get();
>      }
>      private final ConcurrentMap<A, Future<V>> cache =
>          new ConcurrentHashMap<A, Future<V>>();
>      private final Computable<A, V> c;
> }
>
>  I would like to know how put method in Cache can be
>  implemented using FutureTask .
>
>  My put method will be put(key,value).
>
>  I tried creating a dummy task with callable object
>  which returns the value we passed to it  and  it
>  worked fine.
>
>  Is there any good way of implementing the put method?
>
>
>  Tutika
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Implementing Cache

Joe Bowbeer
PS -

Note that my "put" method implementation is more accurately
"putIfAbsent".  If the key is already present in the cache, it returns
the existing FutureTask, else it creates a new FutureTask.

If you really wanted to overwrite/change values in the cache, you
could implement "put" as:

   public void put(A arg, final V val) {
       Callable<V> eval = new Callable<V>() {
           public V call() {
               return val;
           }
       };
       FutureTask<V> ft = new FutureTask<V>(eval);
       cache.put(arg, ft);
       ft.run();
   }

But please read my earlier comments first.  Do you really need the
FutureTask indirection in your application?


On 5/12/06, Joe Bowbeer <[hidden email]> wrote:

> On 5/12/06, Tutika Chakravarthy <[hidden email]> wrote:
> >  I would like to know how put method in Cache can be
> >  implemented using FutureTask .
> >
>
> If you wanted to add a "put" method in order to seed the cache, you
> might implement it as follows:
>
>   public FutureTask<V> put(A arg, final V val) {
>       Future<V> f = cache.get(arg);
>       if (f == null) {
>           Callable<V> eval = new Callable<V>() {
>               public V call() {
>                   return val;
>               }
>           };
>           FutureTask<V> ft = new FutureTask<V>(eval);
>           f = cache.putIfAbsent(arg, ft);
>           if (f == null) {
>               f = ft;
>               ft.run();
>           }
>       }
>       return f;
>   }
>
> Note that the FutureTask "trick" is useful when computing a new value
> for the cache can take a long time.  If the computation time is not an
> issue, however, then you can cache the raw values directly rather than
> using a FutureTask (which can be thought of as a promise to produce a
> value).
>
> If you're using raw values, then your cache could be an instance of
> ConcurrentHashMap and your API could be as simple as cache.get(key)
> and cache.put(key, val).
>
> Also, it might help you to know that the memo-cache example was
> covered in the Bowbeer/Holmes talk at JavaOne 2005, and I believe it
> was also covered in the Goetz/Holmes talk.  Both talks are viewable
> online.
>
> http://java.sun.com/javaone/sf/speaker_awards.jsp
>  http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-3423.html
>  http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-5807.html
>
>
> On 5/12/06, Tutika Chakravarthy <[hidden email]> wrote:
> > Hi All,
> > I have seen the sample code to implement cache using
> > FutureTask and ConcuurentHashMap in one of the threads
> > in this mailing list :
> >
> > code snippet :
> >
> > public interface Computable<A, V> {
> >      V compute(A arg) throws Exception;
> > }
> >
> > public class Memoize<A, V> implements Computable<A, V>
> > {
> >      public Memoize(Computable<A, V> c) {
> >          this.c = c;
> >      }
> >      public V compute(final A arg) throws Exception {
> >          Future<V> f = cache.get(arg);
> >          if (f == null) {
> >              Callable<V> eval = new Callable<V>() {
> >                  public V call() throws Exception {
> >                      return c.compute(arg);
> >                  }
> >              };
> >              FutureTask<V> ft = new
> > FutureTask<V>(eval);
> >              f = cache.putIfAbsent(arg, ft);
> >              if (f == null) { f = ft; ft.run(); }
> >          }
> >          return f.get();
> >      }
> >      private final ConcurrentMap<A, Future<V>> cache =
> >          new ConcurrentHashMap<A, Future<V>>();
> >      private final Computable<A, V> c;
> > }
> >
> >  I would like to know how put method in Cache can be
> >  implemented using FutureTask .
> >
> >  My put method will be put(key,value).
> >
> >  I tried creating a dummy task with callable object
> >  which returns the value we passed to it  and  it
> >  worked fine.
> >
> >  Is there any good way of implementing the put method?
> >
> >
> >  Tutika
> >
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Implementing Cache

Tutika Chakravarthy
In reply to this post by Tutika Chakravarthy

Note: forwarded message attached.


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
> Note that the FutureTask "trick" is useful when
computing a new value
> for the cache can take a long time.  If the
computation time is not an
> issue, however, then you can cache the raw values
directly rather than
> using a FutureTask (which can be thought of as a
promise to produce a
> value)

Thanks for quick reply. Actually our cache requires
this feature. if someone calls get() , if data is not
present in the Cache , we should load it from DataBase
.
So we are planning to use FeatureTask for achiveing
this .

Since we used FeatureTask in get() method , we will
use  FutureTask in put method also , even though there
is no "task" involved in it .

Thanks again for your suggestion.


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest