Statistics
| Revision:

gvsig-raster / org.gvsig.raster.cache / trunk / org.gvsig.raster.cache / org.gvsig.raster.cache.lib.impl / src / main / java / org / gvsig / raster / cache / buffer / impl / stripecache / LRUAlgorithm.java @ 991

History | View | Annotate | Download (7.86 KB)

1
package org.gvsig.raster.cache.buffer.impl.stripecache;
2

    
3
import java.io.IOException;
4

    
5
import org.gvsig.raster.cache.buffer.exception.InvalidPageNumberException;
6
import org.gvsig.raster.cache.buffer.impl.stripecache.horizontal.CacheHorzImpl;
7

    
8
/**
9
 * Esta clase contiene el algoritmo de reemplazo de trozos de cach? LRU
10
 *   
11
 * @author Nacho Brodin (nachobrodin@gmail.com)
12
 *
13
 */
14
public class LRUAlgorithm {
15

    
16
        private Cache cache = null;
17
        
18
        /**
19
         * Constructor. Asigna la cach? para poder aplicar el algoritmo.
20
         * @param cache
21
         */
22
        public LRUAlgorithm(Cache cache){
23
                this.cache = cache;
24
        }
25
        
26
        /**
27
         * Asigna el objeto cach?.
28
         * @param cache 
29
         */
30
        public void setCache(Cache cache) {
31
                this.cache = (CacheHorzImpl)cache;
32
        }
33
        
34
        /*
35
         * (non-Javadoc)
36
         * @see org.gvsig.raster.cache.buffer.impl.stripecache.LRUAlgorithm#cacheAccess(int, boolean)
37
         */
38
        public void cacheAccess(int line, boolean readOnly)throws InvalidPageNumberException, InterruptedException {
39
                int pag = line >> cache.getBitsPag();                        
40
                if(cache.isInCache(pag)) {
41
                        if(cache.getNumberInAccessPage() != pag) {
42
                                loadPage(pag, readOnly);
43
                                //cache.log("loadPage");
44
                        }
45
                } else {
46
                        replacePage(pag + 1, readOnly, false);
47
                        replacePage(pag, readOnly, true);
48
                        //cache.log("replacePage");
49
                }
50
        }
51
        
52
        /**
53
         * Carga la p?gina desde cach? al buffer actualmente en uso. Esta operaci?n no lleva
54
         * cambio de datos sino que solo es un cambio de punteros. La secuencia de operaciones es:
55
         * <UL>
56
         * <LI>Cargar la p?gina como accedida</LI>
57
         * <LI>Asignar n?mero a la p?gina accedida</LI>
58
         * <LI>Actualizar la antig?edad de accesos.Se incrementar? uno en todas las p?ginas del 
59
         * conjunto y se pondr? a 0 la p?gina accedida.</LI>
60
         * <LI>Poner a 0 el valor de lastAccess de la p?gina cargada. Esto hace que tenga m?nima 
61
         * prioridad en la politica de reemplazamiento.</LI>
62
         * <LI>Poner a false el flag de p?gina modificada si el par?metro readOnly es false.</LI>
63
         * </UL>
64
         * @param nPag N?mero de p?gina del raster a la que se intenta acceder.
65
         * @param readOnly ser? true si el acceso que se est? realizando es de lectura y false si se
66
         * est? escribiendo alg?n dato. 
67
         */
68
        private void loadPage(int nPag, boolean readOnly)throws InvalidPageNumberException{
69
                PageBuffer buf = cache.getPageBufferFromNumberRasterPage(nPag);
70
                int[] cacheGroupPage = cache.getNumberGroupFromNumberRasterPage(nPag);
71
                if(buf != null && cacheGroupPage != null){ //Comprueba que el n?mero de p?gina sea correcto para la cach?.
72
                        cache.setAccessPage(buf, nPag);
73
                        cache.updateLastAccess(cacheGroupPage[0]);
74
                        cache.setZeroInLastAccess(cacheGroupPage[0], cacheGroupPage[1]);
75
                        if(!readOnly)
76
                                cache.setModify(cacheGroupPage[0], cacheGroupPage[1]);
77
                }else
78
                        throw new InvalidPageNumberException("");
79
                //System.out.println("LOAD: "+nPag);
80
        }
81
        
82
        /**
83
         * <P>
84
         * Cuando se accede a una p?gina que no est? cacheada necesitamos cargarla en cach? antes de 
85
         * acceder a ella. Si hay un hueco libre en su conjunto se meter? en este pero sino habr? 
86
         * que reemplazar una ocupada. Para esto habr? que localizar el conjunto donde va 
87
         * destinada y luego la posici?n del conjunto donde se cargar? localizando cual es el 
88
         * elemento del conjunto que hace m?s tiempo que se accedi?.
89
         * </P>
90
         * <P>
91
         * Si el elemento es insertado en un hueco la secuencia es la siguiente:
92
         * </P>
93
         * <UL>
94
         * <LI>Obtenemos la siguiente p?gina vacia.</LI>
95
         * <LI>La cargamos de datos.</LI>
96
         * <LI>Se asigna como p?gina accedida</LI>
97
         * <LI>Ponemos true en su posici?n en el vector cacheada</LI>
98
         * <LI>Asignamos el n?mero de p?gina de raster que hemos cargado en esa posici?n de la cach?.</LI>
99
         * <LI>Incrementamos en 1 todos los valores de ?ltimo acceso de las p?ginas del grupo.</LI>
100
         * <LI>Ponemos a 0 su ?ltimo acceso</LI>
101
         * <LI>Si el acceso es para escritura ponemos el flag de p?gina modificada a true.</LI>
102
         * </UL>
103
         * <P>
104
         * Si se reemplaza una p?gina la secuencia es la siguiente:
105
         * </P>
106
         * <UL>
107
         *  <LI>Incrementamos en 1 todos los valores de ?ltimo acceso de las p?ginas del grupo y 
108
         *  obtenemos la posici?n de la p?gina de reemplazo.</LI>
109
         * <LI>Ponemos a false la p?gina que va a sacarse de cach?</LI>
110
         * <LI>Si ha sido modificada la p?gina que va a sacarse de cach? se vuelca a disco</LI>
111
         * <LI>Ponemos el flag de modificada para la p?gina sacada a disco a false.</LI>
112
         * <LI>Cargamos la p?gina de cach? de datos.</LI>
113
         * <LI>Asignamos el n?mero de p?gina de raster que hemos cargado en esa posici?n de la cach?.</LI>
114
         * <LI>Se asigna como p?gina accedida</LI>
115
         * <LI>Ponemos true en su posici?n en el vector cacheada</LI>
116
         * <LI>Ponemos a 0 su ?ltimo acceso</LI>
117
         * <LI>Si el acceso es para escritura ponemos el flag de p?gina modificada a true.</LI>
118
         * </UL>
119
         * @param nPag N?mero de p?gina que est? siendo accedida
120
         * @param readOnly ser? true si el acceso que se est? realizando es de lectura y false si se
121
         * est? escribiendo alg?n dato. 
122
         * @param n ser? true si el acceso se est? haciendo a la p?gina n y false si se est? haciendo a
123
         * la n+1. 
124
         * @throws InterruptedException 
125
         */
126
        private void replacePage(int nPag, boolean readOnly, boolean n) throws InterruptedException {
127
                int group = nPag % cache.getNGroups();
128
                
129
                if(nPag >= cache.getNTotalPags())
130
                        return;
131
                
132
                //Insertamos en un hueco
133
                
134
                if(insertInAGap(group, readOnly, nPag, n))
135
                        return;
136
                                
137
                //Reemplazamos una existente
138
                
139
                int posInGroupPageToReplace = cache.updateLastAccess(group); //Se actualizan los indices y se obtiene la p?gina a reemplazar
140
                
141
                cache.setZeroInLastAccess(group, posInGroupPageToReplace);
142
                int rasterPageToReplace = cache.getRasterPageNumberInPosition(group, posInGroupPageToReplace);
143
                                
144
                //Sacamos la antigua
145
                cache.setPageAsNotLoadInCache(rasterPageToReplace);
146
                if(cache.isModified(group, posInGroupPageToReplace)){
147
                        try {
148
                                cache.savePage(group, posInGroupPageToReplace, rasterPageToReplace);         //Volcamos disco 
149
                                cache.unsetModify(group, posInGroupPageToReplace);
150
                        } catch (IOException e) {
151
                                System.err.println("No se ha podido salvar la p?gina de cach?.");
152
                                e.printStackTrace();
153
                        }
154
                }
155
                
156
                //Insertamos la nueva
157
                cache.loadPage(group, posInGroupPageToReplace, nPag);        //Cargamos de nuevo el buffer
158
                cache.setRasterPageNumberInPosition(group, posInGroupPageToReplace, nPag);
159
                cache.setPageAsLoadInCache(nPag);                //Pone true en su posici?n en el vector cacheada
160
                PageBuffer pb = cache.getPageBuffer(group, posInGroupPageToReplace);
161
                
162
                if(n) {
163
                        if(!readOnly)
164
                                cache.setModify(group, posInGroupPageToReplace);
165
                        cache.setAccessPage(pb, nPag);          //Asigna como accedida
166
                }
167
                //System.out.println("REPLACE: "+nPag);
168
        }
169
        
170
        /**
171
         * Comprueba si hay alg?n hueco en el que insertar y si es as? se inserta en el y devuelve
172
         * true. 
173
         * @param group conjunto donde hay que buscar para la inserci?n
174
         * @param readOnly si es true la operaci?n es de solo consulta y si es false la operaci?n 
175
         * est? modificando alg?n valor de la p?gina a insertar
176
         * @param nPag N?mero de p?gina a cargar
177
         * @return true si se ha insertado en un hueco y false si no se ha insertado
178
         * @throws InterruptedException 
179
         */
180
        private boolean insertInAGap(int group, boolean readOnly, int nPag, boolean n) throws InterruptedException {
181
                PageBuffer pb = null;
182
                for(int i = 0; i < cache.getPagsPerGroup(); i++) {
183
                        if(cache.getLastAccess()[group][i] == -1) {
184

    
185
                                //Pone true en su posici?n en el vector cacheada
186
                                pb = cache.getPageBuffer(group, i);
187
                                cache.loadPage(group, i, nPag);                                        //Sube la p?gina a cach?
188
                                cache.setRasterPageNumberInPosition(group, i, nPag);//Asigna el n?mero de p?g a una posici?n de cach?
189
                                cache.setPageAsLoadInCache(nPag);
190
                                cache.updateLastAccess(group);
191
                                cache.setZeroInLastAccess(group, i);
192
                                if(n){ //La n+1 no se carga como accedida ni se pone a 0 su contador de ?ltima accedida        
193
                                        if(!readOnly)
194
                                                cache.setModify(group, i);
195
                                        cache.setAccessPage(pb, nPag);  //Asigna como accedida
196
                                }                                
197
                                //System.out.println("INSERT: "+nPag);
198
                                return true;
199
                        }
200
                }
201
                return false;
202
        }
203

    
204
}