/[gzz]/gzz/gzz/mem/MemoryPartitioner.java
ViewVC logotype

Diff of /gzz/gzz/mem/MemoryPartitioner.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by tjl, Wed Jan 8 05:40:35 2003 UTC revision 1.2 by tjl, Wed Jan 8 10:35:11 2003 UTC
# Line 3  Line 3 
3  package gzz.mem;  package gzz.mem;
4  import gzz.Obs;  import gzz.Obs;
5    
6    import java.util.*;
7    
8    
9  /** A static API which divides the available memory between  /** A static API which divides the available memory between
10   * MemoryConsumers.   * MemoryConsumers.
# Line 13  public class MemoryPartitioner { Line 15  public class MemoryPartitioner {
15       */       */
16      public static int memory = 64 * 1024 * 1024;      public static int memory = 64 * 1024 * 1024;
17    
18    
19        static Stack currentScene = new Stack();
20        static {
21            currentScene.push(null);
22        }
23    
24        static public void start(Object id) {
25            currentScene.push(id);
26        }
27        static public void end(Object id) {
28            currentScene.pop();
29        }
30    
31      static class ConsumerRecord {      static class ConsumerRecord {
32  //      float          /** The current maximum importance.
33             * May be set to -1 at any time by the background thread.
34             */
35            float maxImportance = -1;
36            float maxQuality = -1;
37    
38            /** The filtered importance.
39             */
40            float curImportance = -1;
41            float curQuality = -1;
42    
43            /** The number of bytes requested from the consumer.
44             */
45            int setBytes = 0;
46            int setQuality = -1;
47    
48            /** The number of bytes the consumer reports using currently.
49             */
50            int gotBytes = 0;
51            int gotQuality = -1;
52    
53            Obs o;
54    
55            /** Update curImportance and curQuality towards the observed
56             * values.
57             */
58            void bgUpdate() {
59                float i = maxImportance;
60                maxImportance = -1;
61                float q = maxQuality;
62                maxQuality = -1;
63    
64                if(i < 0) {
65                    curImportance *= .98;
66                } else {
67                    if(i >= curImportance)
68                        curImportance = i;
69                    else {
70                        curImportance -= .02 * (curImportance - i);
71                    }
72                }
73                // We won't decay: will always remain an interpolate
74                if(q >= 0) {
75                    if(q >= curQuality)
76                        curQuality = q;
77                    else
78                        curQuality -= .02 * (curQuality - q);
79                }
80            }
81    
82            void update(float importance, float quality, Obs o) {
83                if(importance > maxImportance)
84                    maxImportance = importance;
85                if(quality > maxQuality)
86                    maxQuality = quality;
87                this.o = o;
88            }
89    
90      }      }
91    
92   //   Map consumer2      static Map consumer2record = Collections.synchronizedMap(
93                                            new WeakHashMap());
94    
95      /** Indicate that a request for the data of the given consumer was made.      /** Indicate that a request for the data of the given consumer was made.
96       * @param consumer The consumer whose data was requested.       * @param consumer The consumer whose data was requested.
# Line 26  public class MemoryPartitioner { Line 99  public class MemoryPartitioner {
99       * @param quality An abstract value to be passed to       * @param quality An abstract value to be passed to
100       *                          {@link MemoryConsumer#setReservation}. For example,       *                          {@link MemoryConsumer#setReservation}. For example,
101       *                          this could be the DPI resolution of an image.       *                          this could be the DPI resolution of an image.
102         *                          0 = no quality at all, negative values
103         *                          not allowed.
104       * @param o An observer to be called (if non-null)       * @param o An observer to be called (if non-null)
105       *          when the consumer's size is changed the next time.       *          when the consumer's size is changed the next time.
106       *          Note that the semantics are different from {@link MemoryConsumer.setReservation}'s       *          Note that the semantics are different from {@link MemoryConsumer.setReservation}'s
# Line 33  public class MemoryPartitioner { Line 108  public class MemoryPartitioner {
108       *          This difference is up to MemoryPartitioner to handle internally.       *          This difference is up to MemoryPartitioner to handle internally.
109       * @see MemoryConsumer       * @see MemoryConsumer
110       */       */
111      public void request(MemoryConsumer consumer, float importance, float quality, Obs o) {      static public void request(MemoryConsumer consumer, float importance, float quality, Obs o) {
112                    ConsumerRecord rec = (ConsumerRecord)consumer2record.get(consumer);
113            if(rec == null) {
114                rec = new ConsumerRecord();
115                consumer2record.put(consumer, rec);
116            }
117            rec.update(importance, quality, o);
118    
119      }      }
120    
121      static Thread repartitioner = new Thread() {      static Thread repartitioner = new Thread() {
122          public void run() {          public void run() {
123                int sum1 = 0;
124                int sumReduced = 0;
125                for(int round = 0; ; round++) {
126                    for(Iterator i = consumer2record.keySet().iterator(); i.hasNext(); ) {
127                        MemoryConsumer cons = (MemoryConsumer)i.next();
128                        ConsumerRecord rec = (ConsumerRecord)consumer2record.get(cons);
129                        if(round == 0) rec.bgUpdate();
130                        float imp = 0;
131                        if(rec.curImportance > 0)
132                            imp = (float)Math.pow(rec.curImportance, round);
133                        else if(round == 0)
134                            imp = 1;
135                        int byt = cons.getMaxBytes(rec.curQuality);
136                        if(rec.curImportance == 1)
137                            sum1 += byt;
138                        sumReduced += (int)(imp * byt);
139                    }
140                    if(sum1 > memory) {
141                        // Problem! Not enough memory for all 1-importances
142                    }
143                    if(sumReduced <= memory) {
144                        // Hey, now it fits!
145                    }
146                }
147          }          }
148      };      };
149  }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26