Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / buffer / cache / Cache.java @ 2443

History | View | Annotate | Download (25.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.impl.buffer.cache;
23

    
24
import java.io.File;
25
import java.io.FileNotFoundException;
26
import java.io.IOException;
27

    
28
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
29
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
30
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
31
import org.gvsig.raster.impl.datastruct.ExtentImpl;
32
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
33
import org.gvsig.raster.impl.provider.RasterProvider;
34

    
35
/**
36
 * <P>
37
 * Esta clase representa a la cache raster. Consta de una ser?e de p?ginas (CachePages)
38
 * que son buffers con los bloques de datos cacheados en un instante dado. Esta cache tiene 
39
 * una estructura en forma de array donde cada elemento es una p?gina de cach?. Las p?ginas 
40
 * se agrupan en bloques de N p?ginas denominados grupos. La variable nelemsGroup contiene 
41
 * el n?mero de p?ginas de cada grupo.
42
 * </P>
43
 * <P>
44
 * La politica de reemplazo es que una p?gina siempre va a un conjunto determinado por el calculo
45
 * cto = pag % nelemsGroup. Si hay hueco vac?o en el grupo se a?adir? en el siguiente hueco pero
46
 * si hay que reeplazar se reeplazar? la p?gina que m?s tiempo haga su ?ltimo acceso. 
47
 * </P>
48
 * <P>
49
 * Esta cach? lleva el control de que p?ginas est?n cargadas a trav?s de un array de de booleanos
50
 * donde cada elemento representa a una p?gina de datos del raster. Si el elemento en la posici?n
51
 * N de dicho array es true significa que la p?gina est? cacheada. Si es false no lo estar?. 
52
 * </P>
53
 * <P>
54
 * La p?gina de datos actualmente accedida debe estar cacheada por lo que est? clase debe llevar
55
 * el control de que p?gina se est? accediendo o a sido accedida por ?ltima vez. La variable que
56
 * nos dice que p?gina est? siendo accedida es loadPage y pageBuffer ser? la variable que apunta
57
 * al buffer de esta p?gina. Cuando se cambia de p?gina en un acceso estas dos variables deben
58
 * cambiar a sus nuevos valores.
59
 * </P>
60
 * <P>
61
 * Otro par?metro que controla esta clase es que p?gina de cada grupo ha sido accedido con mayor 
62
 * frecuencia. Esto es ?til porque siempre se reemplaza la p?gina de un grupo que haga m?s tiempo
63
 * que haya sido accedida bajo la premisa de que "las p?ginas con accesos recientes tienen mayor 
64
 * probabilidad de volver a ser usadas". Esto es controlado por la variable lastAccess que es
65
 * usada para implementar el algoritmo LRU. Cada vez que una p?gina de un grupo es accedida su 
66
 * contador de lastAccess se pone a 0. El resto de contadores de las p?ginas del grupo se incrementa
67
 * en uno. Siempre se sustituye la p?gina del grupo con valor m?s grande en el contador.
68
 * </P>
69
 * 
70
 * @author Nacho Brodin (nachobrodin@gmail.com)
71
 *
72
 */
73
public class Cache{
74
        /**
75
         * Cada elemento es una p?gina del raster y dice si est? cacheada o no.
76
         */
77
        private boolean[] cacheada = null;
78
        /**
79
         * N?mero de p?gina cargada en accessPage.
80
         */
81
        private int numberInAccessPage = -1;
82
        /**
83
         * Buffer de datos de la p?gina actualmente accedida.
84
         */
85
        private PageBuffer accessPage = null;
86
        /**
87
         * P?ginas de cach?
88
         */
89
        private PageBuffer[] page = null;
90
        /**
91
         * Cada elemento del array es una p?gina de cach? y contiene el n?mero de p?gina cargada en 
92
         * esa posici?n.
93
         */
94
        private int[]        pageNumberInCache = null;
95
        /**
96
         * P?ginas de la cach?.
97
         */
98
        private CacheStruct cacheStruct = null;
99
        /**
100
         * ?ltimo acceso a las p?ginas de cada grupo.
101
         */
102
        private int[][] lastAccess = null;
103
        /**
104
         * Cada elemento representa una p?gina de cach? y dice si esta ha sido modificada desde que
105
         * fu? cargada en cach? o no.
106
         */
107
        private boolean[] modified = null;
108
        /**
109
         * P?ginas de disco
110
         */
111
        private HddPage[] hddPage = null;
112
        
113
        /**
114
         * Inicializamos la variables. Para ello creamos el objeto Cache que contendr? todos los 
115
         * par?metros necesarios para crear el array que controla los accesos m?s recientes y el
116
         * array que dice si una p?gina est? en memoria o no.
117
         * @param nBands N?mero de bandas
118
         * @param dataType Tipo de dato de la p?gina
119
         * @param dataSourceWidth ancho de la fuente de datos
120
         * @param driverParam par?metro para el driver
121
         */
122
        public Cache(int nBands, int dataType, int dataSourceWidth, int dataSourceHeight, Object driverParam)  throws FileNotFoundException, NotSupportedExtensionException, RasterDriverException {
123
                if(driverParam instanceof String) {
124
                        File file = new File(((String)driverParam));
125
                        if(!file.exists())
126
                                throw new FileNotFoundException("I can't make read only cache structure.");
127
                } else 
128
                        return;
129
                
130
                init(nBands, dataType, dataSourceWidth, dataSourceHeight);
131
                
132
                //Creamos las estructuras de las p?ginas de disco
133
                hddPage = new HddPage[cacheStruct.getNTotalPags()];
134
                                
135
                RasterProvider provider = AbstractRasterProvider.singleDatasetInstance(null, (String)driverParam);
136
                Extent[] extentList = calcExtentPages(provider, hddPage.length);
137
                
138
                for (int iPage = 0; iPage < hddPage.length; iPage++)
139
                        hddPage[iPage] = new HddPage(iPage, provider, extentList[iPage]);
140
                
141
                //Creamos las p?ginas de memoria
142
                for(int i = 0; i < cacheStruct.getNPags(); i++) {
143
                  page[i] = new PageBuffer(dataType, dataSourceWidth, cacheStruct.getHPag(), nBands, true, i);
144
                  page[i].setHddPages(hddPage);
145
                }
146
        }
147
        
148
        /**
149
         * Calcula la extensi?n de las p?ginas en coordenadas del mundo real
150
         * @param dataset Dataset
151
         * @param nPages N?mero de p?ginas en que se divide el raster
152
         * @return Extensi?n de cada p?gina
153
         */
154
        private Extent[] calcExtentPages(RasterProvider provider, int nPages) {
155
                Extent datasetExtent = provider.getExtent();
156
                double h = cacheStruct.getHPag() * (provider.getExtent().height() / provider.getHeight());
157
                Extent[] ext = new Extent[nPages];
158
                
159
                double minX = datasetExtent.getMin().getX();
160
                double maxX = datasetExtent.getMax().getX();
161
                double maxY = datasetExtent.getMax().getY();
162
                double minY = maxY - h;
163
                for (int i = 0; i < ext.length; i++) {
164
                        ext[0] = new ExtentImpl(minX, maxY, maxX, minY);
165
                        maxY = minY;
166
                        minY -= h;
167
                }
168
                return ext;
169
        }
170
        
171
        /**
172
         * Inicializamos la variables. Para ello creamos el objeto Cache que contendr? todos los 
173
         * par?metros necesarios para crear el array que controla los accesos m?s recientes y el
174
         * array que dice si una p?gina est? en memoria o no.
175
         * @param nBands N?mero de bandas
176
         * @param dataType Tipo de dato de la p?gina
177
         * @param dataSourceWidth ancho de la fuente de datos
178
         */
179
        public Cache(int nBands, int dataType, int dataSourceWidth, int dataSourceHeight) {
180
                init(nBands, dataType, dataSourceWidth, dataSourceHeight);
181
                
182
                //Creamos las estructuras de las p?ginas de disco
183
                hddPage = new HddPage[cacheStruct.getNTotalPags()];
184
                for (int iPage = 0; iPage < hddPage.length; iPage++)
185
                        hddPage[iPage] = new HddPage(iPage, getNBands());
186
                
187
                //Creamos las p?ginas de memoria
188
                for(int i = 0; i < cacheStruct.getNPags(); i++) {
189
                  page[i] = new PageBuffer(dataType, dataSourceWidth, cacheStruct.getHPag(), nBands, true, i);
190
                  page[i].setHddPages(hddPage);
191
                }
192
        }
193
        
194
        /**
195
         * Contructor
196
         * @param cacheStruct
197
         */
198
        public Cache(CacheStruct cacheStruct, int dataSourceWidth) {
199
                this.cacheStruct = cacheStruct;
200
                
201
                //Inicializamos la antig?edad de acceso  
202
                lastAccess = new int[cacheStruct.getNGroups()][cacheStruct.getPagsPerGroup()];
203
                
204
                //Creamos el buffer de la cach?
205
                page = new PageBuffer[cacheStruct.getNPags()];
206
                pageNumberInCache = new int[cacheStruct.getNPags()];
207
                modified = new boolean[cacheStruct.getNPags()];
208
                cacheada = new boolean[cacheStruct.getNTotalPags()];
209
                
210
                //Creamos las estructuras de las p?ginas de disco
211
                hddPage = new HddPage[cacheStruct.getNTotalPags()];
212
                for (int iPage = 0; iPage < hddPage.length; iPage++)
213
                        hddPage[iPage] = new HddPage(iPage, getNBands());
214
                
215
                //Creamos las p?ginas de memoria
216
                for(int i = 0; i < cacheStruct.getNPags(); i++) {
217
                  page[i] = new PageBuffer(cacheStruct.getDataType(), dataSourceWidth, cacheStruct.getHPag(), cacheStruct.getNBands(), true, i);
218
                  page[i].setHddPages(hddPage);
219
                }
220
                
221
                initStructs();
222
        }
223
        
224
        /**
225
         * 
226
         * @param nBands
227
         * @param dataType
228
         * @param dataSourceWidth
229
         * @param dataSourceHeight
230
         */
231
        private void init(int nBands, int dataType, int dataSourceWidth, int dataSourceHeight) {
232
                //Creamos la estructura de la cach?
233
                cacheStruct = new CacheStruct(nBands, dataType, dataSourceWidth, dataSourceHeight);
234
                
235
                //Inicializamos la antig?edad de acceso  
236
                lastAccess = new int[cacheStruct.getNGroups()][cacheStruct.getPagsPerGroup()];
237
                
238
                //Creamos el buffer de la cach?
239
                page = new PageBuffer[cacheStruct.getNPags()];
240
                pageNumberInCache = new int[cacheStruct.getNPags()];
241
                modified = new boolean[cacheStruct.getNPags()];
242
                cacheada = new boolean[cacheStruct.getNTotalPags()];
243
                
244
                this.initStructs();
245
        }
246
                
247
        /**
248
         * Inicializa las estructuras de mantenimiento de cach?. Estas son array de paginas
249
         * accedidas por ?ltima vez, numeros de p?gina cargadas en cada posici?n de cach?, 
250
         * array con la informaci?n de p?gina modificada y array que dice si una p?gina de disco
251
         * est? cacheada o no.
252
         */
253
        private void initStructs() {
254
                for(int i = 0; i < cacheStruct.getNGroups(); i ++)
255
                        for(int j = 0; j < cacheStruct.getPagsPerGroup(); j ++)
256
                                lastAccess[i][j] = -1;
257
                
258
                for(int i = 0; i < cacheada.length; i++)
259
                        cacheada[i] = false;
260
                
261
                for(int i = 0; i < cacheStruct.getNPags(); i++){
262
                        pageNumberInCache[i] = -1;
263
                        modified[i] = false;
264
                }
265
        }
266
        
267
        /**
268
         * Limpia los trozos de cach? en disco. Despu?s del llamar a este 
269
         * m?todo no puede volver a usarse esta cach?.
270
         * @throws IOException 
271
         */
272
        public void clearCache(int nBands) throws IOException {
273
                if(hddPage == null)
274
                        return;
275
                for (int i = 0; i < hddPage.length; i++) 
276
                        hddPage[i].deletePage(nBands);
277
        }
278
        
279
        /**
280
         * Obtiene el n?mero de bits por p?gina para poder calcular el desplazamiento binario
281
         * de la direcci?n de acceso de la petici?n. Es decir si se solicita un dato en la l?nea
282
         * 36 (en decimal) del raster 100100(en binario) y el desplazamiento es 4 bits el n?mero de 
283
         * p?gina resultante ser? 10(en binario) 2 (en decimal)
284
         * @return
285
         */
286
        public int getBitsPag() {
287
                return cacheStruct.getBitsPag();
288
        }
289

    
290
        /**
291
         * Obtiene la altura de la p?gina de cache en l?neas. 
292
         * @return N?mero de l?neas de altura de p?gina.
293
         */
294
        public int getHPag() {
295
                return cacheStruct.getHPag();
296
        }
297
        
298
        /**
299
         * Array de booleanos donde cada elemento es una p?gina del raster y dice si la p?gina 
300
         * est? cacheada o no.
301
         * @return true si la p?gina est? en cach? y false si no lo est?
302
         */
303
        public boolean isInCache(int nPag) {
304
                if(nPag < 0 || nPag >= cacheada.length)
305
                        return false;
306
                return cacheada[nPag];
307
        }
308
        
309
        /**
310
         * Marca una p?gina como cargada en cach?.
311
         * @param nPag N?mero de p?gina a marcar.
312
         */
313
        public void setPageAsLoadInCache(int nPag) {
314
                if(nPag < 0 || nPag >= cacheada.length)
315
                        return;
316
                cacheada[nPag] = true;
317
        }
318
        
319
        /**
320
         * Desmarca una p?gina como cargada en cach?.
321
         * @param nPag N?mero de p?gina a desmarcar.
322
         */
323
        public void setPageAsNotLoadInCache(int nPag) {
324
                if(nPag < 0 || nPag >= cacheada.length)
325
                        return;
326
                cacheada[nPag] = false;
327
        }
328
        
329
        /**
330
         * Obtiene el n?mero de p?gina del raster cargada en una p?gina de cach? especificada
331
         * en el par?metro. 
332
         * @param nCachePage N?mero de p?gina de cach? de la que se quiere saber que p?gina del 
333
         * raster hay cargada.
334
         * @return N?mero de p?gina del raster
335
         */
336
        public int getRasterPageNumberInPosition(int nCachePage) {
337
                return pageNumberInCache[nCachePage];
338
        }
339
        
340
        /**
341
         * Obtiene el n?mero de p?gina del raster cargada en una p?gina de cach? especificada
342
         * en el par?metro. 
343
         * @param group Grupo en el que se encuentra la p?gina
344
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
345
         * @return N?mero de p?gina del raster
346
         */
347
        public int getRasterPageNumberInPosition(int group, int posInGroup) {
348
                return pageNumberInCache[group * getPagsPerGroup() + posInGroup];
349
        }
350
        
351
        /**
352
         * Asigna el n?mero de p?gina del raster cargada en una p?gina de cach? especificada.
353
         * @param nCachePage N?mero de p?gina de cach? 
354
         * @param nRasterPage N?mero de p?gina de raster a asignar
355
         */
356
        public void setRasterPageNumberInPosition(int nCachePage, int nRasterPage) {
357
                pageNumberInCache[nCachePage] = nRasterPage;
358
        }
359
        
360
        /**
361
         * Asigna el n?mero de p?gina del raster cargada en una p?gina de cach? especificada.
362
         * @param nCachePage N?mero de p?gina de cach? 
363
         * @param nRasterPage N?mero de p?gina de raster a asignar
364
         */
365
        public void setRasterPageNumberInPosition(int group, int posInGroup, int nRasterPage) {
366
                pageNumberInCache[group * getPagsPerGroup() + posInGroup] = nRasterPage;
367
        }
368
        
369
        /**
370
         * Obtiene el n?mero de p?gina de cach? donde est? cargada la p?gina del raster
371
         * que se ha pasado por par?metro.
372
         * @param pag P?gina del raster
373
         * @return N?mero de p?gina del raster
374
         */
375
        public int getNumberCachePageFromNumberRasterPage(int pag) {
376
                int group = pag % getNGroups(); 
377
                for(int i = 0; i < getPagsPerGroup(); i++)
378
                        if(pageNumberInCache[group + i] == pag)
379
                                return (group * getPagsPerGroup() + i);
380
                return -1;
381
        }
382
        
383
        /**
384
         * Obtiene el n?mero de p?gina de cach? (en formato grupo/p?gina dentro del grupo) 
385
         * donde est? cargada la p?gina del raster que se ha pasado por par?metro.
386
         * @param pag P?gina del raster
387
         * @return N?mero de p?gina del raster
388
         */
389
        public int[] getNumberGroupFromNumberRasterPage(int pag) {
390
                int group = pag % getNGroups();
391
                for(int i = 0; i < getPagsPerGroup(); i++)
392
                        if(pageNumberInCache[(group * getPagsPerGroup()) + i] == pag)
393
                                return new int[]{group, i};
394
                return null;
395
        }
396
        
397
        /**
398
         * Obtiene el array que contiene los valores de la antig?edad del acceso dentro del
399
         * grupo. La primera dimensi?n del array corresponde al n?mero de grupo y la segunda
400
         * a los elementos del grupo. El elemento del grupo con un acceso m?s reciente tendr? 
401
         * un n?mero menor y el de mayor valor ser? el candidato para la sustituci?n en el pr?ximo
402
         * remplazamiento.
403
         * @return Array bidimensional con los valores de antig?edad.
404
         */
405
        public int[][] getLastAccess() {
406
                return lastAccess;
407
        }
408

    
409
        /**
410
         * Asigna un cero en la posici?n del array que contiene la antig?edad de acceso dentro 
411
         * del grupo. Esta operaci?n se realiza cada vez que se accede a un dato del la p?gina 
412
         * cacheada y significa que es la p?gina m?s recientemente accedida.
413
         * @param group N?mero de grupo
414
         * @param posInGroup Posici?n de la p?gina dentro del grupo.
415
         */
416
        public void setZeroInLastAccess(int group, int posInGroup) {
417
                lastAccess[group][posInGroup] = 0;
418
        }
419
        
420
        /**
421
         * Obtiene el n?mero de p?gina cargada en el buffer
422
         * @return Entero con el n?mero de p?gina
423
         */
424
        public int getNumberInAccessPage() {
425
                return numberInAccessPage;
426
        }
427

    
428
        /**
429
         * Obtiene el n?mero de p?ginas que tiene cada grupo
430
         * @return Entero con el n?mero de p?ginas por grupo 
431
         */
432
        public int getPagsPerGroup() {
433
                return cacheStruct.getPagsPerGroup();
434
        }
435

    
436
        /**
437
         * Obtiene la p?gina de datos de la posici?n pag
438
         * @param pag N?mero de p?gina de cach? a recuperar
439
         * @return PageBuffer correspondiente a la p?gina recuperada
440
         */
441
        public PageBuffer getPageBufferFromNumberCachePage(int pag) {
442
                return page[pag];
443
        }
444
        
445
        /**
446
         * Obtiene la p?gina de datos a partir del n?mero de p?gina de raster
447
         * @param pag N?mero de p?gina raster a recuperar
448
         * @return PageBuffer correspondiente a la p?gina recuperada o null si no est? en cach?
449
         */
450
        public PageBuffer getPageBufferFromNumberRasterPage(int pag) {
451
                int group = pag % getNGroups();
452
                for(int i = 0; i < getPagsPerGroup(); i++)
453
                        if(pageNumberInCache[group * getPagsPerGroup() + i] == pag)
454
                                return page[group * getPagsPerGroup() + i];
455
                return null;
456
        }
457
        
458
        /**
459
         * Obtiene la p?gina de datos del grupo definido en el par?metro group y de la 
460
         * posici?n pag dentro de ese grupo.
461
         * @param group Grupo de la p?gina requerida
462
         * @param pag N?mero de p?gina dentro del grupo
463
         * @return PageBuffer correspondiente a la p?gina recuperada
464
         */
465
        public PageBuffer getPageBuffer(int group, int posInGroup) {
466
                return page[group * getPagsPerGroup() + posInGroup];
467
        }
468
        
469
        /**
470
         * Obtiene la p?gina de datos actualmente accedida
471
         * @return PageBuffer correspondiente a la p?gina que se est? accediendo
472
         */
473
        public PageBuffer getAccessPage() {
474
                return accessPage;
475
        }
476
        
477
        /**
478
         * Asigna el buffer de la p?gina accedida por referencia
479
         * @param pb
480
         */
481
        public void setAccessPage(PageBuffer pb, int pagNumber) {
482
                accessPage = pb;
483
                numberInAccessPage = pagNumber;
484
        }
485
        
486
        /**
487
         * Consulta si una p?gina de cach? ha sido modificada desde que se carg? en cach? o no.
488
         * @param nCachePag N?mero de p?gina de cach? (posici?n de esta)
489
         * @return true si ha sido modificada y false si no lo ha sido.
490
         */
491
        public boolean isModified(int nCachePag) {
492
                return modified[nCachePag];
493
        }
494

    
495
        /**
496
         * Consulta si una p?gina de cach? ha sido modificada desde que se carg? en cach? o no.
497
         * @param group Grupo en el que se encuentra la p?gina
498
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
499
         * @return true si ha sido modificada y false si no lo ha sido.
500
         */
501
        public boolean isModified(int group, int posInGroup) {
502
                return modified[group * getPagsPerGroup() + posInGroup];
503
        }
504

    
505
        /**
506
         * Pone como modificada una p?gina de cach?
507
         * @param nCachePag N?mero de p?gina de cach? (posici?n de esta)
508
         */
509
        public void setModify(int nCachePag) {
510
                modified[nCachePag] = true;        
511
        }
512
        
513
        /**
514
         * Pone como modificada una p?gina de cach?
515
         * @param group Grupo en el que se encuentra la p?gina
516
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
517
         */
518
        public void setModify(int group, int posInGroup) {
519
                modified[group * getPagsPerGroup() + posInGroup] = true;        
520
        }
521
        
522
        /**
523
         * Pone como no modificada una p?gina de cach?
524
         * @param nCachePag N?mero de p?gina de cach? (posici?n de esta)
525
         */
526
        public void unsetModify(int nCachePag) {
527
                modified[nCachePag] = false;        
528
        }
529
        
530
        /**
531
         * Pone como no modificada una p?gina de cach?
532
         * @param group Grupo en el que se encuentra la p?gina
533
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
534
         */
535
        public void unsetModify(int group, int posInGroup) {
536
                modified[group * getPagsPerGroup() + posInGroup] = false;        
537
        }
538
        
539
        /**
540
         * Obtiene el n?mero de p?ginas de la cach?
541
         * @return N?mero total de p?ginas de la cach?
542
         */
543
        public int getNPags() {
544
                return cacheStruct.getNPags();
545
        }
546
        
547
        /**
548
         * Obtiene el n?mero de bandas
549
         * @return N?mero de bandas
550
         */
551
        public int getNBands() {
552
                return cacheStruct.getNBands();
553
        }
554
        
555
        /**
556
         * Obtiene la estructura de ca cach?
557
         * @return CacheStruct
558
         */
559
        public CacheStruct getCacheStruct() {
560
                return cacheStruct;
561
        }
562
        
563
        /**
564
         * Asigna la estructura de ca cach?
565
         * @param CacheStruct
566
         */
567
        public void setCacheStruct(CacheStruct cacheStruct) {
568
                this.cacheStruct = cacheStruct;
569
        }
570
        
571
        /**
572
         * Obtiene el n?mero de grupos de cach?
573
         * @return N?mero de grupos
574
         */
575
        public int getNGroups() {
576
                return cacheStruct.getNGroups();
577
        }
578
        
579
        /**
580
         * Obtiene el n?mero total de p?ginas del raster
581
         * @return N?mero total de p?ginas
582
         */
583
        public int getNTotalPags() {
584
                return cacheStruct.getNTotalPags();
585
        }
586
        
587
        /**
588
         * Obtiene el array con los n?meros de p?gina que hay cargados
589
         * en cada bloque de cache
590
         * @return array con los n?mero de p?gina
591
         */
592
        public int[] getPageNumberInCache() {
593
                return this.pageNumberInCache;
594
        }
595
        
596
        /**
597
         * Para extraer el desplazamiento de una direcci?n (l?nea de raster) hay que hacer una operaci?n And con 
598
         * con la altura de la p?gina -1. Por ejemplo, una p?gina de 16 l?neas de altura el desplazamiento ser?
599
         * 16 - 1 = 15 porque 15 en binario es 1111.
600
         * 
601
         * Si queremos acceder a la linea del raster n?mero 83 (1010011) realizando la operaci?n And con el valor del
602
         * desplazamiento obtenemos (0001111 & 1010011 = 0000011), es decir el valor 3 en decimal. Esto quiere decir
603
         * que la l?nea 83 del raster es la 3 de su p?gina. 
604
         * @return valor del desplazamiento
605
         */
606
        public int getOffset() {
607
                return cacheStruct.getOffset();
608
        }
609
        
610
        /**
611
         * Convierte una p?gina dentro de un grupo de la cach? en un n?mero de 
612
         * p?gina de cach?. Por ejemplo, en una cach? de 10 grupos y 5 p?ginas por grupo
613
         * la p?gina 2 del grupo 4 devolver? el 23 (5 * 4 + 3 = 23) teniendo en cuenta que
614
         * la p?gina y el grupo cero tambi?n cuentan.  
615
         * @param group
616
         * @param pageInGroup
617
         * @return
618
         */
619
        public int convertPageInGroupToPageInCache(int group, int pageInGroup) {
620
                return (group * cacheStruct.getPagsPerGroup() + pageInGroup);
621
        }
622

    
623
        /**
624
         * Actualiza los ?ltimos accesos del grupo pasado por par?metro. Se incrementar? 
625
         * uno en todas las p?ginas del conjunto a excepci?n de las que valen -1 ya que 
626
         * esto significa que no hay p?gina cargada en dicha posici?n.
627
         * @param group N?mero de grupo a actualizar sus accesos
628
         * @return La posici?n del elemento del grupo con valor m?ximo. Este elemento 
629
         * es el candidato para el reemplazo.
630
         */
631
        public int updateLastAccess(int group) {
632
                int max = Integer.MIN_VALUE;
633
                int posMax = 0;
634
                for(int i = 0; i < getPagsPerGroup(); i++) {
635
                        if(getLastAccess()[group][i] >= 0)
636
                                getLastAccess()[group][i] ++;
637
                        
638
                        if(getLastAccess()[group][i] > max) {
639
                                max = getLastAccess()[group][i];
640
                                posMax = i;
641
                        }
642
                }
643
                return posMax;
644
        }
645
        
646
        /**
647
         * Obtiene la posici?n del grupo de la p?gina a reemplazar, es decir la de m?ximo valor
648
         * en el vector lastAccess.
649
         * @param group N?mero de grupo a obtener la p?gina de reemplazo
650
         * @return La posici?n del elemento del grupo con valor m?ximo. Este elemento 
651
         * es el candidato para el reemplazo.
652
         */
653
        public int posInGroupPagToReplace(int group) {
654
                int max = Integer.MIN_VALUE;
655
                int posMax = 0;
656
                for(int i = 0; i < getPagsPerGroup(); i++) {
657
                        if(getLastAccess()[group][i] > max) {
658
                                max = getLastAccess()[group][i];
659
                                posMax = i;
660
                        }
661
                }
662
                return posMax;
663
        } 
664
        
665
        /**
666
         * Carga una p?gina especificada en el par?metro nPag con los datos necesarios. La
667
         * petici?n que ha de hacerse se calcula previamente con la estructura de la cach?.
668
         *   
669
         * @param group Grupo sobre el que se carga la p?gina nPag
670
         * @param posInGroupPageToReplace Posici?n dentro del grupo sobre el que se carga la p?gina
671
         * @param nPag P?gina a cargar
672
         */
673
        public void loadPage(int group, int posInGroupPageToReplace, int nPag) {
674
                page[group * getPagsPerGroup() + posInGroupPageToReplace].loadPage(nPag);
675
        }
676
        
677
        /**
678
         * Salva una p?gina especificada en el par?metro nPag a disco. La
679
         * petici?n que ha de hacerse se calcula previamente con la estructura de la cach?.
680
         *   
681
         * @param group Grupo del que se salva la p?gina nPag
682
         * @param posInGroupPageToReplace Posici?n dentro del grupo del que se salva la p?gina
683
         * @param nPag P?gina a salvar
684
         * @throws IOException
685
         */
686
        public void savePage(int group, int posInGroupPageToReplace, int nPag) throws IOException {
687
                page[group * getPagsPerGroup() + posInGroupPageToReplace].savePage(nPag);
688
        }
689

    
690
        /**
691
         * Salva a disco todas las p?ginas en memoria cach? e inicializa estructuras de datos.
692
         * 
693
         * @throws IOException
694
         */
695
        public void resetCache() throws IOException {
696
                for (int iCachePage = 0; iCachePage < page.length; iCachePage++) { 
697
                        if(modified[iCachePage])
698
                                page[iCachePage].savePage(this.getRasterPageNumberInPosition(iCachePage));
699
                }
700
                initStructs();
701
        }
702
        
703
        /**
704
         * Elimina una banda de la cach?. Antes salva a disco todos los trozos cacheados e inicializa
705
         * las estructuras de control de cach?. 
706
         * @param nBand N?mero de banda a eliminar
707
         * @throws IOException 
708
         */
709
        public void deleteBand(int nBand) throws IOException {
710
                resetCache();
711
                for (int iPage = 0; iPage < hddPage.length; iPage++)
712
                        hddPage[iPage].deleteBand(nBand);
713
        }
714
        
715
        /**
716
         * Asigna una banda de disco a todas las p?ginas.
717
         * @param cacheDataSource Fuente de las p?ginas. Es la referencia a disco de ellas.
718
         * @throws IOException 
719
         */
720
        public void assignBand(int nBand, ICacheDataSource[] cacheDataSource) throws IOException {
721
                resetCache();
722
                for (int iPage = 0; iPage < hddPage.length; iPage++)
723
                        hddPage[iPage].assignBand(nBand, cacheDataSource[iPage]);
724
        }
725
        
726
        /**
727
         * Obtiene la fuente de datos de una banda de una p?gina de disco.
728
         * @param nPage P?gina de la que se quiere la banda
729
         * @param nBand Banda de la que se quiere la fuente de datos
730
         * @return HddPage
731
         */
732
        public ICacheDataSource getHddPage(int nPage, int nBand) {
733
                return hddPage[nPage].getBandDataSource(nBand);
734
        }
735
        
736
        /**
737
         * Consulta si alguna p?gina de memoria tiene modificaciones para volcar a disco
738
         * @return true si hay alguna p?gina con modificaciones y false si no la hay
739
         */
740
        public boolean anyPageModified() {
741
                for (int iPage = 0; iPage < modified.length; iPage++) {
742
                        if(modified[iPage])
743
                                return true;
744
                }
745
                return false;
746
        }
747
        
748
        /**
749
         * Imprime la informaci?n de estructura de cach?
750
         */
751
        public void show() {
752
                cacheStruct.show();
753
                System.out.println("Cacheada:");
754
                for(int i = 0; i < cacheada.length; i++)
755
                        System.out.print(i + "=" + cacheada[i]+" ");
756
                System.out.println();
757
                System.out.println("LastAccess:");
758
                for(int i = 0; i < cacheStruct.getNGroups(); i++) {
759
                        System.out.println("Grupo " + i +":");
760
                        for(int j = 0; j < cacheStruct.getPagsPerGroup(); j++)
761
                                System.out.println("elem " + j + " : " + "Page " + pageNumberInCache[i * cacheStruct.getPagsPerGroup() + j] + " : " + lastAccess[i][j]);
762
                
763
                }
764
        }
765
        
766
}