Changeset 234c084


Ignore:
Timestamp:
Nov 24, 2009 8:15:29 PM (11 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
95e0492b
Parents:
94faf74
Message:
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    r94faf74 r234c084  
    2121import net.i2p.util.I2PAppThread;
    2222import net.i2p.util.Log;
     23import net.i2p.util.OrderedProperties;
    2324
    2425/**
     
    127128    public void loadConfig(String filename) {
    128129        if (_config == null)
    129             _config = new Properties();
     130            _config = new OrderedProperties();
    130131        if (filename != null) {
    131132            File cfg = new File(filename);
  • core/java/src/net/i2p/util/OrderedProperties.java

    r94faf74 r234c084  
    1010 */
    1111
    12 import java.io.InputStream;
    13 import java.io.OutputStream;
    14 import java.io.PrintStream;
    15 import java.io.PrintWriter;
    16 import java.util.ArrayList;
    17 import java.util.Collection;
    1812import java.util.Collections;
    19 import java.util.Enumeration;
    20 import java.util.HashMap;
    21 import java.util.Iterator;
     13import java.util.Comparator;
    2214import java.util.Map;
    2315import java.util.Properties;
    2416import java.util.Set;
    2517import java.util.TreeSet;
    26 
    27 import net.i2p.data.DataHelper;
    2818
    2919/**
     
    3222 * This does NOT support remove against the iterators / etc. 
    3323 *
     24 * @author zzz Rewritten
     25 *
     26 * Now unsorted until the keyset or entryset is requested.
     27 * The class is unsynchronized.
     28 * The keySet() and entrySet() methods return ordered sets.
     29 * Others - such as the enumerations values(), keys(), propertyNames() - do not.
    3430 */
    3531public class OrderedProperties extends Properties {
    36     private final static Log _log = new Log(OrderedProperties.class);
    37     /** ordered set of keys (strings) stored in the properties */
    38     private TreeSet _order;
    39     /** simple key=value mapping of the actual data */
    40     private Map _data;
    41 
    42     /** lock this before touching _order or _data */
    43     private final Object _lock = new Object();
    4432
    4533    public OrderedProperties() {
    4634        super();
    47         _order = new TreeSet();
    48         _data = new HashMap();
    49     }
    50 
    51     @Override
    52     public boolean contains(Object value) {
    53         return containsValue(value);
    54     }
    55 
    56     @Override
    57     public boolean containsKey(Object key) {
    58         synchronized (_lock) {
    59             return _data.containsKey(key);
    60         }
    61     }
    62 
    63     @Override
    64     public boolean containsValue(Object value) {
    65         synchronized (_lock) {
    66             return _data.containsValue(value);
    67         }
    68     }
    69 
    70     @Override
    71     public boolean equals(Object obj) {
    72         if ((obj != null) && (obj instanceof OrderedProperties)) {
    73             synchronized (_lock) {
    74                 return _data.equals(obj);
    75             }
    76         }
    77        
    78         return false;
    79     }
    80 
    81     @Override
    82     public int hashCode() {
    83         synchronized (_lock) {
    84             return _data.hashCode();
    85         }
    86     }
    87 
    88     @Override
    89     public boolean isEmpty() {
    90         return size() == 0;
    91     }
    92 
    93     @Override
    94     public String getProperty(String key) {
    95         return getProperty((Object) key);
    96     }
    97 
    98     @Override
    99     public Object get(Object key) {
    100         return getProperty(key);
    101     }
    102 
    103     private String getProperty(Object key) {
    104         if (key == null) return null;
    105         synchronized (_lock) {
    106             Object rv = _data.get(key);
    107             if ((rv != null) && (rv instanceof String)) return (String) rv;
    108            
    109             return null;
    110         }
    111     }
    112 
    113     @Override
    114     public Object setProperty(String key, String val) {
    115         if ((key == null) || (val == null)) throw new IllegalArgumentException("Null values are not supported");
    116         synchronized (_lock) {
    117             _order.add(key);
    118             Object rv = _data.put(key, val);
    119             return rv;
    120         }
    121     }
    122 
    123     @Override
    124     public Object put(Object key, Object val) {
    125         if ((key == null) || (val == null)) throw new NullPointerException("Null values or keys are not allowed");
    126         if (!(key instanceof String) || !(val instanceof String))
    127             throw new IllegalArgumentException("Key or value is not a string");
    128         return setProperty((String) key, (String) val);
    129     }
    130 
    131     @Override
    132     public void putAll(Map data) {
    133         if (data == null) return;
    134         for (Iterator iter = data.entrySet().iterator(); iter.hasNext();) {
    135             Map.Entry entry = (Map.Entry)iter.next();
    136             Object key = entry.getKey();
    137             Object val = entry.getValue();
    138             put(key, val);
    139         }
    140     }
    141 
    142     @Override
    143     public Object clone() {
    144         synchronized (_lock) {
    145             OrderedProperties rv = new OrderedProperties();
    146             rv.putAll(this);
    147             return rv;
    148         }
    149     }
    150 
    151     @Override
    152     public void clear() {
    153         synchronized (_lock) {
    154             _order.clear();
    155             _data.clear();
    156         }
    157     }
    158 
    159     @Override
    160     public int size() {
    161         synchronized (_lock) {
    162             return _order.size();
    163         }
    164     }
    165 
    166     @Override
    167     public Object remove(Object key) {
    168         synchronized (_lock) {
    169             _order.remove(key);
    170             Object rv = _data.remove(key);
    171             return rv;
    172         }
    17335    }
    17436
    17537    @Override
    17638    public Set keySet() {
    177         synchronized (_lock) {
    178             return Collections.unmodifiableSortedSet((TreeSet) _order.clone());
    179         }
     39        return Collections.unmodifiableSortedSet(new TreeSet(super.keySet()));
    18040    }
    18141
    18242    @Override
    18343    public Set entrySet() {
    184         synchronized (_lock) {
    185             return Collections.unmodifiableSet(buildEntrySet((TreeSet) _order.clone()));
    186         }
     44        TreeSet rv = new TreeSet(new EntryComparator());
     45        rv.addAll(super.entrySet());
     46        return Collections.unmodifiableSortedSet(rv);
    18747    }
    18848
    189     @Override
    190     public Collection values() {
    191         synchronized (_lock) {
    192             Collection values = new ArrayList(_data.size());
    193             for (Iterator iter = _data.values().iterator(); iter.hasNext();) {
    194                 values.add(iter.next());
    195             }
    196             return values;
    197         }
    198     }
    199 
    200     @Override
    201     public Enumeration elements() {
    202         return Collections.enumeration(values());
    203     }
    204 
    205     @Override
    206     public Enumeration keys() {
    207         return Collections.enumeration(keySet());
    208     }
    209 
    210     @Override
    211     public Enumeration propertyNames() {
    212         return Collections.enumeration(keySet());
    213     }
    214 
    215     @Override
    216     public void list(PrintStream out) { // nop
    217     }
    218 
    219     @Override
    220     public void list(PrintWriter out) { // nop
    221     }
    222 
    223     @Override
    224     public void load(InputStream in) { // nop
    225     }
    226 
    227     //public void save(OutputStream out, String header) {}
    228     @Override
    229     public void store(OutputStream out, String header) { // nop
    230     }
    231 
    232     private Set buildEntrySet(Set data) {
    233         TreeSet ts = new TreeSet();
    234         for (Iterator iter = data.iterator(); iter.hasNext();) {
    235             String key = (String) iter.next();
    236             String val = getProperty(key);
    237             ts.add(new StringMapEntry(key, val));
    238         }
    239         return ts;
    240     }
    241 
    242     private static class StringMapEntry implements Map.Entry, Comparable {
    243         private Object _key;
    244         private Object _value;
    245 
    246         public StringMapEntry(String key, String val) {
    247             _key = key;
    248             _value = val;
    249         }
    250 
    251         public Object getKey() {
    252             return _key;
    253         }
    254 
    255         public Object getValue() {
    256             return _value;
    257         }
    258 
    259         public Object setValue(Object value) {
    260             Object old = _value;
    261             _value = value;
    262             return old;
    263         }
    264 
    265         public int compareTo(Object o) {
    266             if (o == null) return -1;
    267             if (o instanceof StringMapEntry) return ((String) getKey()).compareTo((String)((StringMapEntry) o).getKey());
    268             if (o instanceof String) return ((String) getKey()).compareTo((String)o);
    269             return -2;
    270         }
    271 
    272         /* FIXME missing hashCode() method FIXME */
    273         @Override
    274         public boolean equals(Object o) {
    275             if (o == null) return false;
    276             if (!(o instanceof StringMapEntry)) return false;
    277             StringMapEntry e = (StringMapEntry) o;
    278             return DataHelper.eq(e.getKey(), getKey()) && DataHelper.eq(e.getValue(), getValue());
    279         }
    280     }
    281 
    282     ///
    283     /// tests
    284     ///
    285 
    286     public static void main(String args[]) {
    287         test(new OrderedProperties());
    288         _log.debug("After ordered");
    289         //test(new Properties());
    290         //System.out.println("After normal");
    291         test2();
    292         testThrash();
    293     }
    294 
    295     private static void test2() {
    296         OrderedProperties p = new OrderedProperties();
    297         p.setProperty("a", "b");
    298         p.setProperty("c", "d");
    299         OrderedProperties p2 = new OrderedProperties();
    300         try {
    301             p2.putAll(p);
    302         } catch (Throwable t) {
    303             t.printStackTrace();
    304         }
    305         _log.debug("After test2");
    306     }
    307 
    308     private static void test(Properties p) {
    309         for (int i = 0; i < 10; i++)
    310             p.setProperty(i + "asdfasdfasdf", "qwerasdfqwer");
    311         for (Iterator iter = p.keySet().iterator(); iter.hasNext();) {
    312             String key = (String) iter.next();
    313             String val = p.getProperty(key);
    314             _log.debug("[" + key + "] = [" + val + "]");
    315         }
    316         p.remove(4 + "asdfasdfasdf");
    317         _log.debug("After remove");
    318         for (Iterator iter = p.keySet().iterator(); iter.hasNext();) {
    319             String key = (String) iter.next();
    320             String val = p.getProperty(key);
    321             _log.debug("[" + key + "] = [" + val + "]");
    322         }
    323         try {
    324             p.put("nullVal", null);
    325             _log.debug("Null put did NOT fail!");
    326         } catch (NullPointerException npe) {
    327             _log.debug("Null put failed correctly");
    328         }
    329     }
    330 
    331     /**
    332      * Set 100 concurrent threads trying to do some operations against a single
    333      * OrderedProperties object a thousand times.  Hopefully this will help
    334      * flesh out any synchronization issues.
    335      *
    336      */
    337     private static void testThrash() {
    338         OrderedProperties prop = new OrderedProperties();
    339         for (int i = 0; i < 100; i++)
    340             prop.setProperty(i + "", i + " value");
    341         _log.debug("Thrash properties built");
    342         for (int i = 0; i < 100; i++)
    343             thrash(prop, i);
    344     }
    345 
    346     private static void thrash(Properties props, int i) {
    347         I2PThread t = new I2PThread(new Thrash(props));
    348         t.setName("Thrash" + i);
    349         t.start();
    350     }
    351 
    352     private static class Thrash implements Runnable {
    353         private Properties _props;
    354 
    355         public Thrash(Properties props) {
    356             _props = props;
    357         }
    358 
    359         public void run() {
    360             int numRuns = 1000;
    361             _log.debug("Begin thrashing " + numRuns + " times");
    362             for (int i = 0; i < numRuns; i++) {
    363                 Set keys = _props.keySet();
    364                 //_log.debug("keySet fetched");
    365                 int cur = 0;
    366                 for (Iterator iter = keys.iterator(); iter.hasNext();) {
    367                     Object o = iter.next();
    368                     Object val = _props.get(o);
    369                     //_log.debug("Value " + cur + " fetched");
    370                     cur++;
    371                 }
    372                 //_log.debug("Values fetched");
    373                 int size = _props.size();
    374                 _log.debug("Size calculated");
    375             }
    376             _log.debug("Done thrashing " + numRuns + " times");
     49    private static class EntryComparator implements Comparator {
     50         public int compare(Object l, Object r) {
     51             return ((String)((Map.Entry)l).getKey()).compareTo(((String)((Map.Entry)r).getKey()));
    37752        }
    37853    }
Note: See TracChangeset for help on using the changeset viewer.