s243a

FailureCodeTracker.java (freenet.client)

Oct 22nd, 2014
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.37 KB | None | 0 0
  1. // s243a pearltree node: http://www.pearltrees.com/s243a/failurecodetracker-freenet/id12827793
  2. /* This code is part of Freenet. It is distributed under the GNU General
  3.  * Public License, version 2 (or at your option any later version). See
  4.  * http://www.gnu.org/ for further details of the GPL. */
  5. package freenet.client;
  6.  
  7. import java.util.HashMap;
  8. import java.util.Iterator;
  9. import java.util.Map;
  10.  
  11. import com.db4o.ObjectContainer;
  12.  
  13. import freenet.support.Logger;
  14. import freenet.support.SimpleFieldSet;
  15.  
  16. /**
  17.  * Essentially a map of integer to incrementible integer.
  18.  * FIXME maybe move this to support, give it a better name? Be careful, it's a persistent object, use the
  19.  * db4o migration tools, or derive it from something in support?
  20.  */
  21. public class FailureCodeTracker implements Cloneable {
  22.  
  23.     public final boolean insert;
  24.     private int total;
  25.    
  26.     public FailureCodeTracker(boolean insert) {
  27.         this.insert = insert;
  28.     }
  29.    
  30.     /**
  31.      * Create a FailureCodeTracker from a SimpleFieldSet.
  32.      * @param isInsert Whether this is an insert.
  33.      * @param fs The SimpleFieldSet containing the FieldSet (non-verbose) form of
  34.      * the tracker.
  35.      */
  36.     public FailureCodeTracker(boolean isInsert, SimpleFieldSet fs) {
  37.         this.insert = isInsert;
  38.         Iterator<String> i = fs.directSubsetNameIterator();
  39.         while(i.hasNext()) {
  40.             String name = i.next();
  41.             SimpleFieldSet f = fs.subset(name);
  42.             // We ignore the Description, if there is one; we just want the count
  43.             int num = Integer.parseInt(name);
  44.             int count = Integer.parseInt(f.get("Count"));
  45.             if(count < 0) throw new IllegalArgumentException("Count < 0");
  46.             map.put(Integer.valueOf(num), new Item(count));
  47.             total += count;
  48.         }
  49.     }
  50.    
  51.     private static class Item {
  52.         Item(int count) {
  53.             this.x = count;
  54.         }
  55.  
  56.         Item() {
  57.             this.x = 0;
  58.         }
  59.  
  60.         int x;
  61.     }
  62.  
  63.     private HashMap<Integer, Item> map;
  64.  
  65.     public synchronized void inc(int k) {
  66.         if(k == 0) {
  67.             Logger.error(this, "Can't increment 0, not a valid failure mode", new Exception("error"));
  68.         }
  69.         if(map == null) map = new HashMap<Integer, Item>();
  70.         Integer key = k;
  71.         Item i = map.get(key);
  72.         if(i == null)
  73.             map.put(key, i = new Item());
  74.         i.x++;
  75.         total++;
  76.     }
  77.  
  78.     public synchronized void inc(Integer k, int val) {
  79.         if(k == 0) {
  80.             Logger.error(this, "Can't increment 0, not a valid failure mode", new Exception("error"));
  81.         }
  82.         if(map == null) map = new HashMap<Integer, Item>();
  83.         Integer key = k;
  84.         Item i = map.get(key);
  85.         if(i == null)
  86.             map.put(key, i = new Item());
  87.         i.x+=val;
  88.         total += val;
  89.     }
  90.    
  91.     public synchronized String toVerboseString() {
  92.         if(map == null) return super.toString()+":empty";
  93.         StringBuilder sb = new StringBuilder();
  94.         for (Map.Entry<Integer, Item> e : map.entrySet()) {
  95.             Integer x = e.getKey();
  96.             Item val = e.getValue();
  97.             String s = insert ? InsertException.getMessage(x.intValue()) : FetchException.getMessage(x.intValue());
  98.             sb.append(val.x);
  99.             sb.append('\t');
  100.             sb.append(s);
  101.             sb.append('\n');
  102.         }
  103.         return sb.toString();
  104.     }
  105.  
  106.     @Override
  107.     public synchronized String toString() {
  108.         if(map == null) return super.toString()+":empty";
  109.         StringBuilder sb = new StringBuilder(super.toString());
  110.         sb.append(':');
  111.         if(map.size() == 0) sb.append("empty");
  112.         else if(map.size() == 1) {
  113.             sb.append("one:");
  114.             Integer code = (Integer) (map.keySet().toArray())[0];
  115.             sb.append(code);
  116.             sb.append('=');
  117.             sb.append((map.get(code)).x);
  118.         } else if(map.size() < 10) {
  119.             boolean needComma = false;
  120.             for(Map.Entry<Integer, Item> entry : map.entrySet()) {
  121.                 if(needComma)
  122.                     sb.append(',');
  123.                 sb.append(entry.getKey()); // code
  124.                 sb.append('=');
  125.                 sb.append(entry.getValue().x);
  126.                 needComma = true;
  127.             }
  128.         } else {
  129.             sb.append(map.size());
  130.         }
  131.         return sb.toString();
  132.     }
  133.    
  134.     /**
  135.      * Merge codes from another tracker into this one.
  136.      */
  137.     public synchronized FailureCodeTracker merge(FailureCodeTracker source) {
  138.         if(source.map == null) return this;
  139.         if(map == null) map = new HashMap<Integer, Item>();
  140.         for (Map.Entry<Integer, Item> e : source.map.entrySet()) {
  141.             Integer k = e.getKey();
  142.             Item item = e.getValue();
  143.             inc(k, item.x);
  144.         }
  145.         return this;
  146.     }
  147.  
  148.     public void merge(FetchException e) {
  149.         if(insert) throw new IllegalStateException("Merging a FetchException in an insert!");
  150.         if(e.errorCodes != null) {
  151.             merge(e.errorCodes);
  152.         }
  153.         // Increment mode anyway, so we get the splitfile error as well.
  154.         inc(e.mode);
  155.     }
  156.  
  157.     public synchronized int totalCount() {
  158.         return total;
  159.     }
  160.  
  161.     /** Copy verbosely to a SimpleFieldSet */
  162.     public synchronized SimpleFieldSet toFieldSet(boolean verbose) {
  163.         SimpleFieldSet sfs = new SimpleFieldSet(false);
  164.         if(map != null) {
  165.         for (Map.Entry<Integer, Item> e : map.entrySet()) {
  166.             Integer k = e.getKey();
  167.             Item item = e.getValue();
  168.             int code = k.intValue();
  169.             // prefix.num.Description=<code description>
  170.             // prefix.num.Count=<count>
  171.             if(verbose)
  172.                 sfs.putSingle(Integer.toString(code)+".Description",
  173.                         insert ? InsertException.getMessage(code) : FetchException.getMessage(code));
  174.             sfs.put(Integer.toString(code)+".Count", item.x);
  175.         }
  176.         }
  177.         return sfs;
  178.     }
  179.  
  180.     public synchronized boolean isOneCodeOnly() {
  181.         return map.size() == 1;
  182.     }
  183.  
  184.     public synchronized int getFirstCode() {
  185.         return ((Integer) map.keySet().toArray()[0]).intValue();
  186.     }
  187.  
  188.     public synchronized boolean isFatal(boolean insert) {
  189.         if(map == null) return false;
  190.         for (Map.Entry<Integer, Item> e : map.entrySet()) {
  191.             Integer code = e.getKey();
  192.             if(e.getValue().x == 0) continue;
  193.             if(insert) {
  194.                 if(InsertException.isFatal(code.intValue())) return true;
  195.             } else {
  196.                 if(FetchException.isFatal(code.intValue())) return true;
  197.             }
  198.         }
  199.         return false;
  200.     }
  201.  
  202.     public void merge(InsertException e) {
  203.         if(!insert) throw new IllegalArgumentException("This is not an insert yet merge("+e+") called!");
  204.         if(e.errorCodes != null)
  205.             merge(e.errorCodes);
  206.         inc(e.getMode());
  207.     }
  208.  
  209.     public synchronized boolean isEmpty() {
  210.         return map == null || map.isEmpty();
  211.     }
  212.  
  213.     public void removeFrom(ObjectContainer container) {
  214.         Item[] items;
  215.         Integer[] ints;
  216.         synchronized(this) {
  217.             items = map == null ? null : map.values().toArray(new Item[map.size()]);
  218.             ints = map == null ? null : map.keySet().toArray(new Integer[map.size()]);
  219.             if(map != null) map.clear();
  220.         }
  221.         if(items != null)
  222.             for(int i=0;i<items.length;i++) {
  223.                 container.delete(items[i]);
  224.                 container.delete(ints[i]);
  225.             }
  226.         if(map != null) {
  227.             container.activate(map, 5);
  228.             container.delete(map);
  229.         }
  230.         container.delete(this);
  231.     }
  232.    
  233.     public void objectOnActivate(ObjectContainer container) {
  234.         if(map != null) container.activate(map, 5);
  235.     }
  236.    
  237.     /** Copy the FailureCodeTracker. We implement Cloneable to shut up findbugs, but Object.clone() won't
  238.      * work because it's a shallow copy, so we implement it with merge(). */
  239.     @Override
  240.     public FailureCodeTracker clone() {
  241.         FailureCodeTracker tracker = new FailureCodeTracker(insert);
  242.         tracker.merge(this);
  243.         return tracker;
  244.     }
  245.  
  246.     public void storeTo(ObjectContainer container) {
  247.         // Must store to at least depth 2 because of map.
  248.         container.ext().store(this, 5);
  249.     }
  250.  
  251.     public synchronized boolean isDataFound() {
  252.         for(Map.Entry<Integer, Item> entry : map.entrySet()) {
  253.             if(entry.getValue().x <= 0) continue;
  254.             if(FetchException.isDataFound(entry.getKey(), null)) return true;
  255.         }
  256.         return false;
  257.     }
  258. }
Add Comment
Please, Sign In to add comment