Changeset 3003


Ignore:
Timestamp:
07/20/07 11:33:16 (13 years ago)
Author:
curtis
Message:

Progress on caching logic:

  • CacheEvent for reporting caching events
  • More features in cache CLI tester
  • Package description and better javadocs
Location:
trunk/loci/formats
Files:
4 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/cache/BufferedImageSource.java

    r2984 r3003  
    2424  // -- ICacheSource API methods -- 
    2525 
    26   /* @see loci.formats.cache.ICacheSource#getObject(int[], int[]) */ 
    27   public Object getObject(int[] len, int[] pos) throws CacheException { 
    28     int ndx = FormatTools.positionToRaster(len, pos); 
    29     try { return reader.openImage(ndx); } 
     26  /* @see loci.formats.cache.ICacheSource#getObject(int) */ 
     27  public Object getObject(int index) throws CacheException { 
     28    try { return reader.openImage(index); } 
    3029    catch (FormatException exc) { throw new CacheException(exc); } 
    3130    catch (IOException exc) { throw new CacheException(exc); } 
  • trunk/loci/formats/cache/ByteArraySource.java

    r2984 r3003  
    2424  // -- ICacheSource API methods -- 
    2525 
    26   /* @see loci.formats.cache.ICacheSource#getObject(int[], int[]) */ 
    27   public Object getObject(int[] len, int[] pos) throws CacheException { 
    28     int ndx = FormatTools.positionToRaster(len, pos); 
    29     try { return reader.openBytes(ndx); } 
     26  /* @see loci.formats.cache.ICacheSource#getObject(int) */ 
     27  public Object getObject(int index) throws CacheException { 
     28    try { return reader.openBytes(index); } 
    3029    catch (FormatException exc) { throw new CacheException(exc); } 
    3130    catch (IOException exc) { throw new CacheException(exc); } 
  • trunk/loci/formats/cache/Cache.java

    r2980 r3003  
    77import java.io.*; 
    88import java.util.Arrays; 
     9import java.util.Vector; 
    910import javax.swing.JFrame; 
    1011import loci.formats.*; 
    1112 
    12 public class Cache { 
    13  
    14   // -- Static fields -- 
    15  
    16   /** Whether to generate debugging output. */ 
    17   private static boolean debug = false; 
     13/** 
     14 * Cache provides a means of managing subsets of large collections of image 
     15 * planes in memory. Each cache has a source, which provides image planes or 
     16 * other objects from somewhere (typically derived from an IFormatReader), 
     17 * and a strategy dictating which image planes should be loaded into the cache, 
     18 * in which order, and which planes should be dropped from the cache. The 
     19 * essence of the logic is the idea that the cache has a "current" position 
     20 * across the multidimensional image series's dimensional axes, with the 
     21 * strategy indicating which surrounding planes to load into the cache (i.e., 
     22 * planes within a certain range along each dimensional axis). 
     23 */ 
     24public class Cache implements CacheReporter { 
    1825 
    1926  // -- Fields -- 
    2027 
    2128  /** Current cache strategy. */ 
    22   private ICacheStrategy strategy; 
     29  protected ICacheStrategy strategy; 
    2330 
    2431  /** Current cache source. */ 
    25   private ICacheSource source; 
     32  protected ICacheSource source; 
    2633 
    2734  /** Current dimensional position. */ 
    28   private int[] currentPos; 
     35  protected int[] currentPos; 
    2936 
    3037  /** Master array containing cached objects. */ 
    31   private Object[] cache; 
     38  protected Object[] cache; 
    3239 
    3340  /** Whether each position is currently supposed to be cached. */ 
    34   private boolean[] inCache; 
     41  protected boolean[] inCache; 
     42 
     43  /** List of cache event listeners. */ 
     44  protected Vector listeners; 
    3545 
    3646  // -- Constructors -- 
     
    4454    this.strategy = strategy; 
    4555    this.source = source; 
     56    listeners = new Vector(); 
    4657    reset(); 
    4758  } 
     
    6071  } 
    6172 
    62   /** Clears the cache. */ 
     73  /** Reallocates the cache. */ 
    6374  public void reset() throws CacheException { 
    6475    currentPos = new int[strategy.getLengths().length]; 
    6576    cache = new Object[source.getObjectCount()]; 
    6677    inCache = new boolean[source.getObjectCount()]; 
    67     Arrays.fill(inCache, false); 
    6878  } 
    6979 
     
    8090  public void setStrategy(ICacheStrategy strategy) throws CacheException { 
    8191    if (strategy == null) throw new CacheException("strategy is null"); 
     92    synchronized (listeners) { 
     93      for (int i=0; i<listeners.size(); i++) { 
     94        CacheListener l = (CacheListener) listeners.elementAt(i); 
     95        this.strategy.removeCacheListener(l); 
     96        strategy.addCacheListener(l); 
     97      } 
     98    } 
    8299    this.strategy = strategy; 
    83     reset(); 
    84     load(currentPos); 
     100    notifyListeners(new CacheEvent(this, CacheEvent.STRATEGY_CHANGED)); 
     101//    reset(); 
     102//    recache(); 
    85103  } 
    86104 
     
    89107    if (source == null) throw new CacheException("source is null"); 
    90108    this.source = source; 
    91     reset(); 
    92     load(currentPos); 
     109    notifyListeners(new CacheEvent(this, CacheEvent.SOURCE_CHANGED)); 
     110//    reset(); 
     111//    recache(); 
    93112  } 
    94113 
     
    108127    } 
    109128    System.arraycopy(pos, 0, currentPos, 0, pos.length); 
    110     load(currentPos); 
     129    int ndx = FormatTools.positionToRaster(len, pos); 
     130    notifyListeners(new CacheEvent(this, CacheEvent.POSITION_CHANGED, ndx)); 
     131//    recache(); 
     132  } 
     133 
     134  // -- CacheReporter API methods -- 
     135 
     136  /* @see CacheReporter#addCacheListener(CacheListener) */ 
     137  public void addCacheListener(CacheListener l) { 
     138    synchronized (listeners) { 
     139      listeners.add(l); 
     140      strategy.addCacheListener(l); 
     141    } 
     142  } 
     143 
     144  /* @see CacheReporter#removeCacheListener(CacheListener) */ 
     145  public void removeCacheListener(CacheListener l) { 
     146    synchronized (listeners) { 
     147      listeners.remove(l); 
     148      strategy.removeCacheListener(l); 
     149    } 
     150  } 
     151 
     152  /* @see CacheReporter#getCacheListeners() */ 
     153  public CacheListener[] getCacheListeners() { 
     154    CacheListener[] l; 
     155    synchronized (listeners) { 
     156      l = new CacheListener[listeners.size()]; 
     157      listeners.copyInto(l); 
     158    } 
     159    return l; 
    111160  } 
    112161 
    113162  // -- Helper methods -- 
    114163 
    115   private void load(int[] pos) throws CacheException { 
    116     int[][] indices = strategy.getLoadList(pos); 
     164  protected void recache() throws CacheException { 
     165    // what happens if cache source and cache strategy lengths do not match? 
     166    // throw exception in that case 
     167    // what if developer wants to change both source and strategy to something 
     168    // completely different -- make sure it works 
     169    // in general, what if developer wants to tweak a few parameters before 
     170    // starting to reload things? probably should have a recache method that 
     171    // you must explicitly call to trigger the separate thread refresh 
     172    // need to be careful -- don't want cache parameter changes affecting the 
     173    // recaching thread on the fly -- should refresh those parameter values 
     174    // each time through the loop only (i.e., only when a recache call occurs) 
     175    // 
     176    // /lo 
     177    int[][] indices = strategy.getLoadList(currentPos); 
    117178    int[] len = strategy.getLengths(); 
    118179 
     
    124185 
    125186    for (int i=0; i<cache.length; i++) { 
    126       if (!inCache[i]) cache[i] = null; 
     187      if (!inCache[i] && cache[i] != null) { 
     188        cache[i] = null; 
     189        notifyListeners(new CacheEvent(this, CacheEvent.OBJECT_DROPPED, i)); 
     190      } 
    127191    } 
    128192 
     
    130194      int ndx = FormatTools.positionToRaster(len, indices[i]); 
    131195      if (cache[ndx] == null) { 
    132         if (debug) printArray("Loading position", indices[i]); 
    133         cache[ndx] = source.getObject(len, indices[i]); 
    134       } 
    135       else if (debug) printArray("Already in cache", indices[i]); 
    136     } 
    137   } 
    138  
    139   /** Helper utility for outputting contents of an int array, used by main. */ 
    140   private static final void printArray(String name, int[] array) { 
    141     LogTools.print(name + " ="); 
    142     for (int i=0; i<array.length; i++) LogTools.print(" " + array[i]); 
    143     LogTools.println(); 
    144   } 
    145  
    146   /** Helper utility for constructing lengths array, used by main. */ 
    147   private static final int[] getLengths(IFormatReader r) { 
    148     return new int[] {r.getSizeZ(), r.getSizeC(), r.getSizeT()}; 
     196        cache[ndx] = source.getObject(ndx); 
     197        notifyListeners(new CacheEvent(this, CacheEvent.OBJECT_LOADED, ndx)); 
     198      } 
     199    } 
     200  } 
     201 
     202  /** Informs listeners of a cache update. */ 
     203  protected void notifyListeners(CacheEvent e) { 
     204    synchronized (listeners) { 
     205      for (int i=0; i<listeners.size(); i++) { 
     206        CacheListener l = (CacheListener) listeners.elementAt(i); 
     207        l.cacheUpdated(e); 
     208      } 
     209    } 
    149210  } 
    150211 
     
    157218      System.exit(1); 
    158219    } 
    159     debug = true; 
    160220    ImageReader reader = new ImageReader(); 
    161221    String id = args[0]; 
     
    163223    reader.setId(id); 
    164224    LogTools.println("Initializing cache"); 
    165     Cache cache = new Cache( 
     225    final Cache cache = new Cache( 
    166226      new CrosshairStrategy(getLengths(reader)), 
    167227      new BufferedImageSource(reader)); 
     228    CacheListener l = new CacheListener() { 
     229      public void cacheUpdated(CacheEvent e) { 
     230        int type = e.getType(); 
     231        int ndx = e.getIndex(); 
     232        int[] len, pos; 
     233        switch (type) { 
     234          case CacheEvent.SOURCE_CHANGED: 
     235            printSource("source ->", cache); 
     236            break; 
     237          case CacheEvent.STRATEGY_CHANGED: 
     238            printStrategy("strategy ->", cache); 
     239            break; 
     240          case CacheEvent.POSITION_CHANGED: 
     241            len = cache.getStrategy().getLengths(); 
     242            pos = FormatTools.rasterToPosition(len, ndx); 
     243            printArray("pos ->", pos); 
     244            break; 
     245          case CacheEvent.PRIORITIES_CHANGED: 
     246            printArray("priorities ->", cache.getStrategy().getPriorities()); 
     247            break; 
     248          case CacheEvent.ORDER_CHANGED: 
     249            printOrder("order ->", cache); 
     250            break; 
     251          case CacheEvent.RANGE_CHANGED: 
     252            printArray("range ->", cache.getStrategy().getRange()); 
     253            break; 
     254          case CacheEvent.OBJECT_LOADED: 
     255            len = cache.getStrategy().getLengths(); 
     256            pos = FormatTools.rasterToPosition(len, ndx); 
     257            printArray("loaded:", pos); 
     258            break; 
     259          case CacheEvent.OBJECT_DROPPED: 
     260            len = cache.getStrategy().getLengths(); 
     261            pos = FormatTools.rasterToPosition(len, ndx); 
     262            printArray("dropped:", pos); 
     263            break; 
     264        } 
     265      } 
     266    }; 
     267    cache.addCacheListener(l); 
    168268    BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); 
    169269    LogTools.println("Entering Bio-Formats caching test console"); 
     
    172272      String cmd = r.readLine().trim(); 
    173273      if (cmd.equals("")) continue; 
     274      else if (cmd.startsWith("c")) { // cache 
     275        cache.recache(); 
     276      } 
    174277      else if (cmd.startsWith("e") || cmd.startsWith("q")) break; // exit/quit 
    175278      else if (cmd.startsWith("g")) { // gui 
     
    193296      else if (cmd.startsWith("h")) { // help 
    194297        LogTools.println("Available commands:"); 
     298        LogTools.println("  cache    -- begins loading planes into the cache"); 
    195299        LogTools.println("  gui      -- pops up a GUI to configure the cache"); 
    196300        LogTools.println("  info     -- displays the cache state"); 
     
    198302        LogTools.println("  strategy -- changes the cache strategy"); 
    199303        LogTools.println("  source   -- changes the cache source"); 
     304        LogTools.println("  priority -- changes the cache priorities"); 
     305        LogTools.println("  order    -- changes the cache order"); 
    200306        LogTools.println("  range    -- changes the cache ranges"); 
    201         LogTools.println("  priority -- changes the cache priorities"); 
    202307        LogTools.println("  read     -- gets a plane from the cache"); 
    203308        LogTools.println("  exit     -- quits the interpreter"); 
     
    205310      else if (cmd.startsWith("i")) { // info 
    206311        // output dimensional position 
    207         printArray("pos", cache.getCurrentPos()); 
     312        printArray("pos =", cache.getCurrentPos()); 
    208313        // output source information 
    209314        ICacheSource source = cache.getSource(); 
    210         LogTools.print("source = "); 
    211         Class sourceClass = source.getClass(); 
    212         if (sourceClass == BufferedImageSource.class) { 
    213           LogTools.println("BufferedImage"); 
    214         } 
    215         else if (sourceClass == ByteArraySource.class) { 
    216           LogTools.println("byte array"); 
    217         } 
    218         else if (sourceClass == ImageProcessorSource.class) { 
    219           LogTools.println("ImageProcessor"); 
    220         } 
    221         else LogTools.println("unknown"); 
     315        printSource("source =", cache); 
    222316        LogTools.println("object count = " + source.getObjectCount()); 
    223317        // output strategy information 
    224318        ICacheStrategy strategy = cache.getStrategy(); 
    225         LogTools.print("strategy = "); 
    226         Class strategyClass = strategy.getClass(); 
    227         if (strategyClass == CrosshairStrategy.class) { 
    228           LogTools.println("crosshair"); 
    229         } 
    230         else if (strategyClass == RectangleStrategy.class) { 
    231           LogTools.println("crosshair"); 
    232         } 
    233         else LogTools.println("unknown"); 
    234         printArray("priorities", strategy.getPriorities()); 
    235         int[] order = strategy.getOrder(); 
    236         LogTools.print("order ="); 
    237         for (int i=0; i<order.length; i++) { 
    238           switch (order[i]) { 
    239             case ICacheStrategy.CENTERED_ORDER: 
    240               LogTools.print(" C"); 
    241               break; 
    242             case ICacheStrategy.FORWARD_ORDER: 
    243               LogTools.print(" F"); 
    244               break; 
    245             case ICacheStrategy.BACKWARD_ORDER: 
    246               LogTools.print(" B"); 
    247               break; 
    248             default: 
    249               LogTools.print(" ?"); 
    250           } 
    251         } 
    252         LogTools.println(); 
    253         printArray("range", strategy.getRange()); 
    254         printArray("lengths", strategy.getLengths()); 
     319        printStrategy("strategy =", cache); 
     320        printArray("priorities =", strategy.getPriorities()); 
     321        printOrder("order =", cache); 
     322        printArray("range =", strategy.getRange()); 
     323        printArray("lengths =", strategy.getLengths()); 
     324      } 
     325      else if (cmd.startsWith("o")) { // order 
     326        LogTools.println(ICacheStrategy.CENTERED_ORDER + " => centered"); 
     327        LogTools.println(ICacheStrategy.FORWARD_ORDER + " => forward"); 
     328        LogTools.println(ICacheStrategy.BACKWARD_ORDER + " => backward"); 
     329        LogTools.print("Z: "); 
     330        int z = Integer.parseInt(r.readLine().trim()); 
     331        LogTools.print("C: "); 
     332        int c = Integer.parseInt(r.readLine().trim()); 
     333        LogTools.print("T: "); 
     334        int t = Integer.parseInt(r.readLine().trim()); 
     335        ICacheStrategy strategy = cache.getStrategy(); 
     336        strategy.setOrder(z, 0); 
     337        strategy.setOrder(c, 1); 
     338        strategy.setOrder(t, 2); 
    255339      } 
    256340      else if (cmd.startsWith("po")) { // position 
     
    312396          case 0: 
    313397            cache.setSource(new BufferedImageSource(reader)); 
    314             LogTools.println("Source set to BufferedImage"); 
    315398            break; 
    316399          case 1: 
    317400            cache.setSource(new ByteArraySource(reader)); 
    318             LogTools.println("Source set to byte array"); 
    319401            break; 
    320402          case 2: 
    321403            cache.setSource(new ImageProcessorSource(reader)); 
    322             LogTools.println("Source set to ImageProcessor"); 
    323404            break; 
    324405          default: 
     
    331412        LogTools.print("> "); 
    332413        int n = Integer.parseInt(r.readLine().trim()); 
    333         int[] l = getLengths(reader); 
     414        int[] zct = getLengths(reader); 
     415        ICacheStrategy strategy = null; 
    334416        switch (n) { 
    335417          case 0: 
    336             cache.setStrategy(new CrosshairStrategy(l)); 
    337             LogTools.println("Strategy set to crosshair"); 
     418            strategy = new CrosshairStrategy(zct); 
    338419            break; 
    339420          case 1: 
    340             cache.setStrategy(new RectangleStrategy(l)); 
    341             LogTools.println("Strategy set to rectangle"); 
     421            strategy = new RectangleStrategy(zct); 
    342422            break; 
    343423          default: 
    344424            LogTools.println("Unknown strategy: " + n); 
    345425        } 
     426        if (strategy != null) { 
     427          ICacheStrategy old = cache.getStrategy(); 
     428          int[] priorities = old.getPriorities(); 
     429          int[] range = old.getRange(); 
     430          int[] order = old.getOrder(); 
     431          for (int i=0; i<zct.length; i++) { 
     432            strategy.setPriority(priorities[i], i); 
     433            strategy.setRange(range[i], i); 
     434            strategy.setOrder(order[i], i); 
     435          } 
     436          cache.setStrategy(strategy); 
     437        } 
    346438      } 
    347439      else LogTools.println("Unknown command: " + cmd); 
     
    350442  } 
    351443 
     444  /** Helper utility for outputing contents of an int array, used by main. */ 
     445  private static final void printArray(String prefix, int[] array) { 
     446    LogTools.print(prefix); 
     447    if (array == null) LogTools.println(" null"); 
     448    else { 
     449      for (int i=0; i<array.length; i++) LogTools.print(" " + array[i]); 
     450      LogTools.println(); 
     451    } 
     452  } 
     453 
     454  /** Helper utility for outputing cache's associated source, used by main. */ 
     455  private static final void printSource(String prefix, Cache cache) { 
     456    ICacheSource source = cache.getSource(); 
     457    LogTools.print(prefix + " "); 
     458    Class sourceClass = source.getClass(); 
     459    if (sourceClass == BufferedImageSource.class) { 
     460      LogTools.println("BufferedImage"); 
     461    } 
     462    else if (sourceClass == ByteArraySource.class) { 
     463      LogTools.println("byte array"); 
     464    } 
     465    else if (sourceClass == ImageProcessorSource.class) { 
     466      LogTools.println("ImageProcessor"); 
     467    } 
     468    else LogTools.println("unknown"); 
     469  } 
     470 
     471  /** Helper utility for outputing cache's associated strategy, used by main. */ 
     472  private static final void printStrategy(String prefix, Cache cache) { 
     473    ICacheStrategy strategy = cache.getStrategy(); 
     474    LogTools.print(prefix + " "); 
     475    Class strategyClass = strategy.getClass(); 
     476    if (strategyClass == CrosshairStrategy.class) { 
     477      LogTools.println("crosshair"); 
     478    } 
     479    else if (strategyClass == RectangleStrategy.class) { 
     480      LogTools.println("rectangle"); 
     481    } 
     482    else LogTools.println("unknown"); 
     483  } 
     484 
     485  /** Helper utility for outputing cache strategy's order, used by main. */ 
     486  private static final void printOrder(String prefix, Cache cache) { 
     487    ICacheStrategy strategy = cache.getStrategy(); 
     488    int[] order = strategy.getOrder(); 
     489    LogTools.print(prefix); 
     490    for (int i=0; i<order.length; i++) { 
     491      switch (order[i]) { 
     492        case ICacheStrategy.CENTERED_ORDER: 
     493          LogTools.print(" C"); 
     494          break; 
     495        case ICacheStrategy.FORWARD_ORDER: 
     496          LogTools.print(" F"); 
     497          break; 
     498        case ICacheStrategy.BACKWARD_ORDER: 
     499          LogTools.print(" B"); 
     500          break; 
     501        default: 
     502          LogTools.print(" ?"); 
     503      } 
     504    } 
     505    LogTools.println(); 
     506  } 
     507 
     508  /** Helper utility for constructing lengths array, used by main. */ 
     509  private static final int[] getLengths(IFormatReader r) { 
     510    return new int[] {r.getSizeZ(), r.getSizeC(), r.getSizeT()}; 
     511  } 
     512 
    352513} 
  • trunk/loci/formats/cache/CacheSource.java

    r2984 r3003  
    99 
    1010/** 
    11  * Retrieves image planes from a data source 
    12  * (e.g., a file) using Bio-Formats. 
     11 * Superclass of cache sources that retrieve image planes 
     12 * from a data source (e.g., a file) using Bio-Formats. 
    1313 */ 
    1414public abstract class CacheSource implements ICacheSource { 
     
    3737  public int getObjectCount() { return reader.getImageCount(); } 
    3838 
    39   /* @see ICacheSource#getObject(int[], int[]) */ 
    40   public abstract Object getObject(int[] len, int[] pos) throws CacheException; 
     39  /* @see ICacheSource#getObject(int) */ 
     40  public abstract Object getObject(int index) throws CacheException; 
    4141 
    4242} 
  • trunk/loci/formats/cache/CacheStrategy.java

    r2974 r3003  
    55package loci.formats.cache; 
    66 
    7 import java.util.Arrays; 
    8 import java.util.Comparator; 
     7import java.util.*; 
    98import loci.formats.FormatTools; 
    109 
    11 public abstract class CacheStrategy implements Comparator, ICacheStrategy { 
     10/** Superclass of cache strategies. */ 
     11public abstract class CacheStrategy 
     12  implements CacheReporter, Comparator, ICacheStrategy 
     13{ 
    1214 
    1315  // -- Constants -- 
     
    2123  protected int[] lengths; 
    2224 
    23   /** The order in which slices should be loaded along each axis. */ 
     25  /** The order in which planes should be loaded along each axis. */ 
    2426  protected int[] order; 
    2527 
     
    3133 
    3234  /** 
    33    * The list of dimensional positions to consider caching, 
    34    * in order of preference based on strategy, axis priority and slice order. 
     35   * The list of dimensional positions to consider caching, in order of 
     36   * preference based on strategy, axis priority and planar ordering. 
    3537   */ 
    3638  private int[][] positions; 
     
    4143   */ 
    4244  private boolean dirty; 
     45 
     46  /** List of cache event listeners. */ 
     47  protected Vector listeners; 
    4348 
    4449  // -- Constructors -- 
     
    5560    positions = getPossiblePositions(); 
    5661    dirty = true; 
     62    listeners = new Vector(); 
    5763  } 
    5864 
    5965  // -- Abstract CacheStrategy API methods -- 
    6066 
     67  /** 
     68   * Gets positions to consider for possible inclusion in the cache, 
     69   * assuming a current position at the origin (0). 
     70   */ 
    6171  protected abstract int[][] getPossiblePositions(); 
    6272 
    6373  // -- CacheStrategy API methods -- 
    64  
    65   public int raster(int[] pos) { 
    66     return FormatTools.positionToRaster(lengths, pos); 
    67   } 
    68  
    69   public int[] pos(int raster) { 
    70     return FormatTools.rasterToPosition(lengths, raster); 
    71   } 
    72  
    73   public int[] pos(int raster, int[] pos) { 
    74     return FormatTools.rasterToPosition(lengths, raster, pos); 
    75   } 
    76  
    77   public int length() { return FormatTools.getRasterLength(lengths); } 
    7874 
    7975  /** 
     
    9692  } 
    9793 
     94  // -- Internal CacheStrategy API methods -- 
     95 
     96  /** Shortcut for converting N-D position to rasterized position. */ 
     97  protected int raster(int[] pos) { 
     98    return FormatTools.positionToRaster(lengths, pos); 
     99  } 
     100 
     101  /** Shortcut for converting rasterized position to N-D position. */ 
     102  protected int[] pos(int raster) { 
     103    return FormatTools.rasterToPosition(lengths, raster); 
     104  } 
     105 
     106  /** 
     107   * Shortcut for converting rasterized position to N-D position, 
     108   * using the given array instead of allocating a new one. 
     109   */ 
     110  protected int[] pos(int raster, int[] pos) { 
     111    return FormatTools.rasterToPosition(lengths, raster, pos); 
     112  } 
     113 
     114  /** Shortcut for computing total number of positions. */ 
     115  protected int length() { return FormatTools.getRasterLength(lengths); } 
     116 
     117  // -- CacheReporter API methods -- 
     118 
     119  /* @see CacheReporter#addCacheListener(CacheListener) */ 
     120  public void addCacheListener(CacheListener l) { 
     121    synchronized (listeners) { listeners.add(l); } 
     122  } 
     123 
     124  /* @see CacheReporter#removeCacheListener(CacheListener) */ 
     125  public void removeCacheListener(CacheListener l) { 
     126    synchronized (listeners) { listeners.remove(l); } 
     127  } 
     128 
     129  /* @see CacheReporter#getCacheListeners() */ 
     130  public CacheListener[] getCacheListeners() { 
     131    CacheListener[] l; 
     132    synchronized (listeners) { 
     133      l = new CacheListener[listeners.size()]; 
     134      listeners.copyInto(l); 
     135    } 
     136    return l; 
     137  } 
     138 
    98139  // -- Comparator API methods -- 
    99140 
    100141  /** 
    101142   * Default comparator orders dimensional positions based on distance from the 
    102    * current position, taking into account axis priorities and slice ordering. 
     143   * current position, taking into account axis priorities and planar ordering. 
    103144   */ 
    104145  public int compare(Object o1, Object o2) { 
     
    199240      dirty = true; 
    200241    } 
     242    notifyListeners(new CacheEvent(this, CacheEvent.PRIORITIES_CHANGED)); 
    201243  } 
    202244 
     
    216258      dirty = true; 
    217259    } 
     260    notifyListeners(new CacheEvent(this, CacheEvent.ORDER_CHANGED)); 
    218261  } 
    219262 
     
    222265 
    223266  /* @see ICacheStrategy#setRange(int, int) */ 
    224   public void setRange(int planes, int axis) { 
    225     if (planes < 0) { 
     267  public void setRange(int num, int axis) { 
     268    if (num < 0) { 
    226269      throw new IllegalArgumentException( 
    227         "Invalid range for axis #" + axis + ": " + planes); 
    228     } 
    229     range[axis] = planes; 
     270        "Invalid range for axis #" + axis + ": " + num); 
     271    } 
     272    range[axis] = num; 
     273    notifyListeners(new CacheEvent(this, CacheEvent.RANGE_CHANGED)); 
    230274  } 
    231275 
     
    233277  public int[] getLengths() { return lengths; } 
    234278 
     279  // -- Helper methods -- 
     280   
     281  /** Informs listeners of a cache update. */ 
     282  protected void notifyListeners(CacheEvent e) { 
     283    synchronized (listeners) { 
     284      for (int i=0; i<listeners.size(); i++) { 
     285        CacheListener l = (CacheListener) listeners.elementAt(i); 
     286        l.cacheUpdated(e); 
     287      } 
     288    } 
     289  } 
     290 
    235291} 
  • trunk/loci/formats/cache/CrosshairStrategy.java

    r2973 r3003  
    4848    int[][] p = new int[len][lengths.length]; 
    4949    for (int i=0, c=0; i<lengths.length; i++) { 
    50       for (int j=1; j<lengths[i]; j++) { 
    51         p[++c][i] = j; 
    52       } 
     50      for (int j=1; j<lengths[i]; j++) p[++c][i] = j; 
    5351    } 
    5452    return p; 
  • trunk/loci/formats/cache/ICacheSource.java

    r2984 r3003  
    55package loci.formats.cache; 
    66 
     7/** 
     8 * Interface for cache sources. A cache source returns objects 
     9 * in a defined order, from 0 to getObjectCount() - 1. 
     10 * The actual source of the objects is implementation-dependent; 
     11 * Bio-Formats uses {@link loci.formats.IFormatReader} to obtain image planes, 
     12 * but any ordered collection of objects can conceivably be cached. 
     13 */ 
    714public interface ICacheSource { 
    815 
     
    1118 
    1219  /** Get the object corresponding to the given index. */ 
    13   Object getObject(int[] len, int[] pos) throws CacheException; 
     20  Object getObject(int index) throws CacheException; 
    1421 
    1522} 
  • trunk/loci/formats/cache/ICacheStrategy.java

    r2969 r3003  
    55package loci.formats.cache; 
    66 
    7 public interface ICacheStrategy { 
     7/** 
     8 * Interface for cache strategies. A cache strategy identifies which 
     9 * objects should be loaded into the cache, in which order. Unlike 
     10 * {@link ICacheSource}, it works with multidimensional (N-D) position arrays 
     11 * rather than rasterized (1-D) indices. The two are made equivalent via a 
     12 * mapping between the two, invoked within {@link Cache} as needed. 
     13 */ 
     14public interface ICacheStrategy extends CacheReporter { 
    815 
    916  // -- Constants -- 
     
    2330  /** 
    2431   * Gets the indices of the objects to cache, 
    25    * surrounding the object with the given index. 
     32   * surrounding the object at the given position. 
    2633   */ 
    2734  int[][] getLoadList(int[] pos) throws CacheException; 
     
    3441 
    3542  /** 
    36    * Retrieves the order in which slices should be loaded along each axis. 
     43   * Retrieves the order in which objects should be loaded along each axis. 
    3744   * @return An array whose constituents are each one of:<ul> 
    3845   *   <li>CENTERED_ORDER</li> 
     
    4350 
    4451  /** 
    45    * Sets the order in which slices should be loaded along each axis. 
     52   * Sets the order in which objects should be loaded along each axis. 
    4653   * @param order One of:<ul> 
    4754   *   <li>CENTERED_ORDER</li> 
     
    5259  void setOrder(int order, int axis); 
    5360 
    54   /** Retrieves the number of planes to cache along each axis. */ 
     61  /** Retrieves the number of objects to cache along each axis. */ 
    5562  int[] getRange(); 
    5663 
    57   /** Sets the number of planes to cache along the given axis. */ 
    58   void setRange(int planes, int axis); 
     64  /** Sets the number of objects to cache along the given axis. */ 
     65  void setRange(int num, int axis); 
    5966 
    6067  /** Gets the lengths of all the axes. */ 
  • trunk/loci/formats/cache/ImageProcessorSource.java

    r2984 r3003  
    5858   * (one per channel). 
    5959   * 
    60    * @see loci.formats.cache.ICacheSource#getObject(int[], int[]) 
     60   * @see loci.formats.cache.ICacheSource#getObject(int) 
    6161   */ 
    62   public Object getObject(int[] len, int[] pos) throws CacheException { 
     62  public Object getObject(int index) throws CacheException { 
    6363    if (noIJ) throw new CacheException(NO_IJ_MSG); 
    64  
    65     int ndx = FormatTools.positionToRaster(len, pos); 
    6664 
    6765    try { 
     
    7270      int bpp = FormatTools.getBytesPerPixel(type); 
    7371 
    74       byte[] b = reader.openBytes(ndx); 
     72      byte[] b = reader.openBytes(index); 
    7573 
    7674      if (b.length != w * h * c * bpp && b.length != w * h * bpp) { 
     
    7876        // a different size, but we have no way of knowing what size; 
    7977        // so open this plane as a BufferedImage to find out 
    80         BufferedImage bi = reader.openImage(ndx); 
     78        BufferedImage bi = reader.openImage(index); 
    8179        b = ImageTools.padImage(b, reader.isInterleaved(), c, 
    8280          bi.getWidth() * bpp, w, h); 
  • trunk/loci/formats/gui/CacheComponent.java

    r2980 r3003  
    1818{ 
    1919 
     20  // -- Constants -- 
     21 
     22  protected static final String[] STRATEGIES = {"Crosshair", "Rectangle"}; 
     23  protected static final String[] PRIORITIES = 
     24    {"maximum", "high", "normal", "low", "minimum"}; 
     25  protected static final String[] ORDER = {"centered", "forward", "backward"}; 
     26 
    2027  // -- Fields -- 
    2128 
     
    2532  /** File that the cache is working with. */ 
    2633  private String file; 
    27  
    28   /** Length of each axis. */ 
    29   private int[] lengths; 
    3034 
    3135  /** Spinners for choosing range of slices to cache. */ 
     
    4347    this.cache = cache; 
    4448    this.file = file; 
    45     this.lengths = cache.getStrategy().getLengths(); 
    46  
    47     // constants 
    48     final String[] strategies = new String[] {"Crosshair", "Rectangle"}; 
    49     final String[] priorities = {"max", "high", "normal", "low", "min"}; 
    50     final String[] order = {"centered", "forward", "backward"}; 
    5149 
    5250    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
     
    5755 
    5856    JPanel top = new JPanel(); 
    59     FormLayout layout = new FormLayout("pref:grow,3dlu,pref:grow", 
     57    FormLayout layout = new FormLayout("pref,3dlu,pref:grow", 
    6058      doSource ? "pref:grow,3dlu,pref:grow" : "pref:grow"); 
    6159    top.setLayout(layout); 
     
    7573 
    7674    // add strategy choices 
    77  
    7875    JLabel label = new JLabel("Caching strategy: "); 
    7976    top.add(label, cc.xy(1, doSource ? 3 : 1)); 
    80     JComboBox strategyChooser = new JComboBox(strategies); 
     77    JComboBox strategyChooser = new JComboBox(STRATEGIES); 
    8178    strategyChooser.setActionCommand("strategy"); 
    8279    strategyChooser.addActionListener(this); 
    8380    top.add(strategyChooser, cc.xy(3, doSource ? 3 : 1)); 
    84  
    8581    add(top); 
    8682 
     
    10197    middle.add(new JLabel("Order"), cc.xy(7, 1)); 
    10298 
     99    int[] lengths = cache.getStrategy().getLengths(); 
    103100    for (int i=0; i<axisLabels.length; i++) { 
    104101      JLabel l = new JLabel(axisLabels[i]); 
     
    107104      middle.add(r, cc.xy(3, i*2 + 3)); 
    108105      range.add(r); 
    109       JComboBox prio = new JComboBox(priorities); 
     106      JComboBox prio = new JComboBox(PRIORITIES); 
     107      prio.setSelectedIndex(PRIORITIES.length / 2); 
    110108      middle.add(prio, cc.xy(5, i*2 + 3)); 
    111       JComboBox ord = new JComboBox(order); 
     109      JComboBox ord = new JComboBox(ORDER); 
    112110      middle.add(ord, cc.xy(7, i*2 + 3)); 
    113111    } 
     
    126124  // -- CacheComponent API methods -- 
    127125 
    128   public Cache getCache() { 
    129     return cache; 
    130   } 
     126  public Cache getCache() { return cache; } 
    131127 
    132128  // -- ActionListener API methods -- 
     
    229225 
    230226    try { 
     227      int[] lengths = cache.getStrategy().getLengths(); 
    231228      if (s.startsWith("Crosshair")) { 
    232229        strategy = new CrosshairStrategy(lengths); 
     
    235232        strategy = new RectangleStrategy(lengths); 
    236233      } 
    237 //      strategy.setForwardFirst(forwardFirst); 
    238234      int[] rng = getRange(); 
    239235      for (int i=0; i<rng.length; i++) strategy.setRange(rng[i], i); 
Note: See TracChangeset for help on using the changeset viewer.