[icedtea-web] RFC: move TimedHashMap to netx

Dr Andrew John Hughes ahughes at redhat.com
Tue Feb 15 05:20:52 PST 2011


On 18:44 Mon 14 Feb     , Omair Majid wrote:
> On 02/14/2011 05:42 PM, Dr Andrew John Hughes wrote:
> > On 16:33 Mon 14 Feb     , Omair Majid wrote:
> >> Hi,
> >>
> >> The attached patch moves TimeHashMap from
> >> plugin/icedteanp/java/sun/applet/PluginProxySelector.java to
> >> netx/net/sourceforge/jnlp/util/TimedHashMap.java, so other
> >> ProxySelectors can also use it. My patch for adding proxy auto config
> >> support will be using this new class.
> >>
> >> Other than the movement, there are a few minor changes to it:
> >> - It no longer extends HashMap. TimedHashMap did not override all the
> >>     HashMap methods and it was possible to see inconsistent data. By
> >>     reducing the interface, this should not be a problem any more (the
> >>     plugin code still compiles fine).
> >> - The use of Date has been replaced by System.nanoTime(). This should
> >>     give us a more monotonic clock and be less susceptible to clock
> >>     changes (especially to moving the clock backwards).
> >>
> >> Any thoughts or concerns?
> >>
> >
> > Could you do the move in a separate patch to the other changes?
> > Otherwise, the changes are unclear as the file appears new.
> >
> 
> Good point. I have split it into two patches. part1 contains all the 
> changes necessary to move TimedHashMap and make it compile (including 
> the PluginDebug changes). part2 contains the actual changes in 
> TimedHashMap (not extending HashMap and using System.nanoTime()).
> 
> Any other comments?
> 
> Cheers,
> Omair

The changes look fine now.  I like how wrapping instead of extending
HashMap means we can now have a more typesafe get method.

> diff -r 1ffa1308adbe netx/net/sourceforge/jnlp/util/TimedHashMap.java
> --- a/netx/net/sourceforge/jnlp/util/TimedHashMap.java	Mon Feb 14 18:36:18 2011 -0500
> +++ b/netx/net/sourceforge/jnlp/util/TimedHashMap.java	Mon Feb 14 18:38:06 2011 -0500
> @@ -37,7 +37,6 @@
>  
>  package net.sourceforge.jnlp.util;
>  
> -import java.util.Date;
>  import java.util.HashMap;
>  
>  import net.sourceforge.jnlp.runtime.JNLPRuntime;
> @@ -47,14 +46,14 @@
>   *
>   * This map stores entries, and returns them only if the entries were last accessed within time t=10 seconds
>   *
> - * @param <K> The key type
> - * @param <V> The Object type
> + * @param K The key type
> + * @param V The Object type
>   */
> +public class TimedHashMap<K, V> {
>  
> -public class TimedHashMap<K, V> extends HashMap<K, V> {
> -
> +    HashMap<K,V> actualMap = new HashMap<K,V>();
>      HashMap<K, Long> timeStamps = new HashMap<K, Long>();
> -    Long expiry = 10000L;
> +    Long expiry = 10000000000L;
>  
>      /**
>       * Store the item in the map and associate a timestamp with it
> @@ -63,8 +62,8 @@
>       * @param value The value to store
>       */
>      public V put(K key, V value) {
> -        timeStamps.put(key, new Date().getTime());
> -        return super.put(key, value);
> +        timeStamps.put(key, System.nanoTime());
> +        return actualMap.put(key, value);
>      }
>  
>      /**
> @@ -75,24 +74,22 @@
>       *
>       * @param key The key
>       */
> -    @SuppressWarnings("unchecked")
> -    public V get(Object key) {
> +    public V get(K key) {
> +        Long now = System.nanoTime();
>  
> -        Long now = new Date().getTime();
> -
> -        if (super.containsKey(key)) {
> +        if (actualMap.containsKey(key)) {
>              Long age = now - timeStamps.get(key);
>  
>              // Item exists. If it has not expired, renew its access time and return it
>              if (age <= expiry) {
>                  if (JNLPRuntime.isDebug()) {
> -                    System.err.println("Returning proxy " + super.get(key) + " from cache for " + key);
> +                    System.err.println("Returning proxy " + actualMap.get(key) + " from cache for " + key);
>                  }
> -                timeStamps.put((K) key, (new Date()).getTime());
> -                return super.get(key);
> +                timeStamps.put(key, System.nanoTime());
> +                return actualMap.get(key);
>              } else {
>                  if (JNLPRuntime.isDebug()) {
> -                    System.err.println("Proxy cache for " + key + " has expired (age=" + age / 1000.0 + " seconds)");
> +                    System.err.println("Proxy cache for " + key + " has expired (age=" + (age * 1e-9) + " seconds)");
>                  }
>              }
>          }
> @@ -100,3 +97,4 @@
>          return null;
>      }
>  }
> +

> diff -r c6f717dfcb97 -r 1ffa1308adbe netx/net/sourceforge/jnlp/util/TimedHashMap.java
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/netx/net/sourceforge/jnlp/util/TimedHashMap.java	Mon Feb 14 18:36:18 2011 -0500
> @@ -0,0 +1,102 @@
> +/* TimedHashMap.java
> +   Copyright (C) 2011 Red Hat, Inc.
> +
> +This file is part of IcedTea.
> +
> +IcedTea is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 2, or (at your option)
> +any later version.
> +
> +IcedTea is distributed in the hope that it will be useful, but
> +WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with IcedTea; see the file COPYING.  If not, write to the
> +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> +02110-1301 USA.
> +
> +Linking this library statically or dynamically with other modules is
> +making a combined work based on this library.  Thus, the terms and
> +conditions of the GNU General Public License cover the whole
> +combination.
> +
> +As a special exception, the copyright holders of this library give you
> +permission to link this library with independent modules to produce an
> +executable, regardless of the license terms of these independent
> +modules, and to copy and distribute the resulting executable under
> +terms of your choice, provided that you also meet, for each linked
> +independent module, the terms and conditions of the license of that
> +module.  An independent module is a module which is not derived from
> +or based on this library.  If you modify this library, you may extend
> +this exception to your version of the library, but you are not
> +obligated to do so.  If you do not wish to do so, delete this
> +exception statement from your version. */
> +
> +package net.sourceforge.jnlp.util;
> +
> +import java.util.Date;
> +import java.util.HashMap;
> +
> +import net.sourceforge.jnlp.runtime.JNLPRuntime;
> +
> +/**
> + * Simple utility class that extends HashMap by adding an expiry to the entries.
> + *
> + * This map stores entries, and returns them only if the entries were last accessed within time t=10 seconds
> + *
> + * @param <K> The key type
> + * @param <V> The Object type
> + */
> +
> +public class TimedHashMap<K, V> extends HashMap<K, V> {
> +
> +    HashMap<K, Long> timeStamps = new HashMap<K, Long>();
> +    Long expiry = 10000L;
> +
> +    /**
> +     * Store the item in the map and associate a timestamp with it
> +     *
> +     * @param key The key
> +     * @param value The value to store
> +     */
> +    public V put(K key, V value) {
> +        timeStamps.put(key, new Date().getTime());
> +        return super.put(key, value);
> +    }
> +
> +    /**
> +     * Return cached item if it has not already expired.
> +     *
> +     * Before returning, this method also resets the "last accessed"
> +     * time for this entry, so it is good for another 10 seconds
> +     *
> +     * @param key The key
> +     */
> +    @SuppressWarnings("unchecked")
> +    public V get(Object key) {
> +
> +        Long now = new Date().getTime();
> +
> +        if (super.containsKey(key)) {
> +            Long age = now - timeStamps.get(key);
> +
> +            // Item exists. If it has not expired, renew its access time and return it
> +            if (age <= expiry) {
> +                if (JNLPRuntime.isDebug()) {
> +                    System.err.println("Returning proxy " + super.get(key) + " from cache for " + key);
> +                }
> +                timeStamps.put((K) key, (new Date()).getTime());
> +                return super.get(key);
> +            } else {
> +                if (JNLPRuntime.isDebug()) {
> +                    System.err.println("Proxy cache for " + key + " has expired (age=" + age / 1000.0 + " seconds)");
> +                }
> +            }
> +        }
> +
> +        return null;
> +    }
> +}
> diff -r c6f717dfcb97 -r 1ffa1308adbe plugin/icedteanp/java/sun/applet/PluginProxySelector.java
> --- a/plugin/icedteanp/java/sun/applet/PluginProxySelector.java	Fri Feb 11 20:13:11 2011 -0500
> +++ b/plugin/icedteanp/java/sun/applet/PluginProxySelector.java	Mon Feb 14 18:36:18 2011 -0500
> @@ -40,12 +40,11 @@
>  import java.net.InetSocketAddress;
>  import java.net.Proxy;
>  import java.net.URI;
> -import java.util.Date;
>  import java.util.ArrayList;
> -import java.util.HashMap;
>  import java.util.List;
>  
>  import net.sourceforge.jnlp.runtime.JNLPProxySelector;
> +import net.sourceforge.jnlp.util.TimedHashMap;
>  
>  /**
>   * Proxy selector implementation for plugin network functions.
> @@ -129,59 +128,4 @@
>          return null;
>      }
>  
> -    /**
> -     * Simple utility class that extends HashMap by adding an expiry to the entries.
> -     *
> -     * This map stores entries, and returns them only if the entries were last accessed within time t=10 seconds
> -     *
> -     * @param <K> The key type
> -     * @param <V> The Object type
> -     */
> -
> -    private class TimedHashMap<K, V> extends HashMap<K, V> {
> -
> -        HashMap<K, Long> timeStamps = new HashMap<K, Long>();
> -        Long expiry = 10000L;
> -
> -        /**
> -         * Store the item in the map and associate a timestamp with it
> -         *
> -         * @param key The key
> -         * @param value The value to store
> -         */
> -        public V put(K key, V value) {
> -            timeStamps.put(key, new Date().getTime());
> -            return super.put(key, value);
> -        }
> -
> -        /**
> -         * Return cached item if it has not already expired.
> -         *
> -         * Before returning, this method also resets the "last accessed"
> -         * time for this entry, so it is good for another 10 seconds
> -         *
> -         * @param key The key
> -         */
> -        @SuppressWarnings("unchecked")
> -        public V get(Object key) {
> -
> -            Long now = new Date().getTime();
> -
> -            if (super.containsKey(key)) {
> -                Long age = now - timeStamps.get(key);
> -
> -                // Item exists. If it has not expired, renew its access time and return it
> -                if (age <= expiry) {
> -                    PluginDebug.debug("Returning proxy " + super.get(key) + " from cache for " + key);
> -                    timeStamps.put((K) key, (new Date()).getTime());
> -                    return super.get(key);
> -                } else {
> -                    PluginDebug.debug("Proxy cache for " + key + " has expired (age=" + age / 1000.0 + " seconds)");
> -                }
> -            }
> -
> -            return null;
> -        }
> -    }
> -
>  }
> 


-- 
Andrew :)

Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)

Support Free Java!
Contribute to GNU Classpath and IcedTea
http://www.gnu.org/software/classpath
http://icedtea.classpath.org
PGP Key: F5862A37 (https://keys.indymedia.org/)
Fingerprint = EA30 D855 D50F 90CD F54D  0698 0713 C3ED F586 2A37



More information about the distro-pkg-dev mailing list