Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataaccess / cache / Cache.java @ 10782

History | View | Annotate | Download (23.7 KB)

1

    
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 */
20
package org.gvsig.raster.dataaccess.cache;
21

    
22
import java.io.File;
23
import java.io.FileNotFoundException;
24
import java.io.IOException;
25

    
26
import org.gvsig.raster.driver.NotSupportedExtensionException;
27
import org.gvsig.raster.driver.RasterDataset;
28
import org.gvsig.raster.driver.RasterDriverException;
29
import org.gvsig.raster.shared.Extent;
30

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

    
240
        /**
241
         * Obtiene la altura de la p?gina de cache en l?neas. 
242
         * @return N?mero de l?neas de altura de p?gina.
243
         */
244
        public int getHPag() {
245
                return cacheStruct.getHPag();
246
        }
247
        
248
        /**
249
         * Array de booleanos donde cada elemento es una p?gina del raster y dice si la p?gina 
250
         * est? cacheada o no.
251
         * @return true si la p?gina est? en cach? y false si no lo est?
252
         */
253
        public boolean isInCache(int nPag) {
254
                if(nPag < 0 || nPag >= cacheada.length)
255
                        return false;
256
                return cacheada[nPag];
257
        }
258
        
259
        /**
260
         * Marca una p?gina como cargada en cach?.
261
         * @param nPag N?mero de p?gina a marcar.
262
         */
263
        public void setPageAsLoadInCache(int nPag) {
264
                if(nPag < 0 || nPag >= cacheada.length)
265
                        return;
266
                cacheada[nPag] = true;
267
        }
268
        
269
        /**
270
         * Desmarca una p?gina como cargada en cach?.
271
         * @param nPag N?mero de p?gina a desmarcar.
272
         */
273
        public void setPageAsNotLoadInCache(int nPag) {
274
                if(nPag < 0 || nPag >= cacheada.length)
275
                        return;
276
                cacheada[nPag] = false;
277
        }
278
        
279
        /**
280
         * Obtiene el n?mero de p?gina del raster cargada en una p?gina de cach? especificada
281
         * en el par?metro. 
282
         * @param nCachePage N?mero de p?gina de cach? de la que se quiere saber que p?gina del 
283
         * raster hay cargada.
284
         * @return N?mero de p?gina del raster
285
         */
286
        public int getRasterPageNumberInPosition(int nCachePage) {
287
                return pageNumberInCache[nCachePage];
288
        }
289
        
290
        /**
291
         * Obtiene el n?mero de p?gina del raster cargada en una p?gina de cach? especificada
292
         * en el par?metro. 
293
         * @param group Grupo en el que se encuentra la p?gina
294
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
295
         * @return N?mero de p?gina del raster
296
         */
297
        public int getRasterPageNumberInPosition(int group, int posInGroup) {
298
                return pageNumberInCache[group * getPagsPerGroup() + posInGroup];
299
        }
300
        
301
        /**
302
         * Asigna el n?mero de p?gina del raster cargada en una p?gina de cach? especificada.
303
         * @param nCachePage N?mero de p?gina de cach? 
304
         * @param nRasterPage N?mero de p?gina de raster a asignar
305
         */
306
        public void setRasterPageNumberInPosition(int nCachePage, int nRasterPage) {
307
                pageNumberInCache[nCachePage] = nRasterPage;
308
        }
309
        
310
        /**
311
         * Asigna el n?mero de p?gina del raster cargada en una p?gina de cach? especificada.
312
         * @param nCachePage N?mero de p?gina de cach? 
313
         * @param nRasterPage N?mero de p?gina de raster a asignar
314
         */
315
        public void setRasterPageNumberInPosition(int group, int posInGroup, int nRasterPage) {
316
                pageNumberInCache[group * getPagsPerGroup() + posInGroup] = nRasterPage;
317
        }
318
        
319
        /**
320
         * Obtiene el n?mero de p?gina de cach? donde est? cargada la p?gina del raster
321
         * que se ha pasado por par?metro.
322
         * @param pag P?gina del raster
323
         * @return N?mero de p?gina del raster
324
         */
325
        public int getNumberCachePageFromNumberRasterPage(int pag) {
326
                int group = pag % getNGroups(); 
327
                for(int i = 0; i < getPagsPerGroup(); i++)
328
                        if(pageNumberInCache[group + i] == pag)
329
                                return (group * getPagsPerGroup() + i);
330
                return -1;
331
        }
332
        
333
        /**
334
         * Obtiene el n?mero de p?gina de cach? (en formato grupo/p?gina dentro del grupo) 
335
         * donde est? cargada la p?gina del raster que se ha pasado por par?metro.
336
         * @param pag P?gina del raster
337
         * @return N?mero de p?gina del raster
338
         */
339
        public int[] getNumberGroupFromNumberRasterPage(int pag) {
340
                int group = pag % getNGroups();
341
                for(int i = 0; i < getPagsPerGroup(); i++)
342
                        if(pageNumberInCache[(group * getPagsPerGroup()) + i] == pag)
343
                                return new int[]{group, i};
344
                return null;
345
        }
346
        
347
        /**
348
         * Obtiene el array que contiene los valores de la antig?edad del acceso dentro del
349
         * grupo. La primera dimensi?n del array corresponde al n?mero de grupo y la segunda
350
         * a los elementos del grupo. El elemento del grupo con un acceso m?s reciente tendr? 
351
         * un n?mero menor y el de mayor valor ser? el candidato para la sustituci?n en el pr?ximo
352
         * remplazamiento.
353
         * @return Array bidimensional con los valores de antig?edad.
354
         */
355
        public int[][] getLastAccess() {
356
                return lastAccess;
357
        }
358

    
359
        /**
360
         * Asigna un cero en la posici?n del array que contiene la antig?edad de acceso dentro 
361
         * del grupo. Esta operaci?n se realiza cada vez que se accede a un dato del la p?gina 
362
         * cacheada y significa que es la p?gina m?s recientemente accedida.
363
         * @param group N?mero de grupo
364
         * @param posInGroup Posici?n de la p?gina dentro del grupo.
365
         */
366
        public void setZeroInLastAccess(int group, int posInGroup) {
367
                lastAccess[group][posInGroup] = 0;
368
        }
369
        
370
        /**
371
         * Obtiene el n?mero de p?gina cargada en el buffer
372
         * @return Entero con el n?mero de p?gina
373
         */
374
        public int getNumberInAccessPage() {
375
                return numberInAccessPage;
376
        }
377

    
378
        /**
379
         * Obtiene el n?mero de p?ginas que tiene cada grupo
380
         * @return Entero con el n?mero de p?ginas por grupo 
381
         */
382
        public int getPagsPerGroup() {
383
                return cacheStruct.getPagsPerGroup();
384
        }
385

    
386
        /**
387
         * Obtiene la p?gina de datos de la posici?n pag
388
         * @param pag N?mero de p?gina de cach? a recuperar
389
         * @return PageBuffer correspondiente a la p?gina recuperada
390
         */
391
        public PageBuffer getPageBufferFromNumberCachePage(int pag) {
392
                return page[pag];
393
        }
394
        
395
        /**
396
         * Obtiene la p?gina de datos a partir del n?mero de p?gina de raster
397
         * @param pag N?mero de p?gina raster a recuperar
398
         * @return PageBuffer correspondiente a la p?gina recuperada o null si no est? en cach?
399
         */
400
        public PageBuffer getPageBufferFromNumberRasterPage(int pag) {
401
                int group = pag % getNGroups();
402
                for(int i = 0; i < getPagsPerGroup(); i++)
403
                        if(pageNumberInCache[group * getPagsPerGroup() + i] == pag)
404
                                return page[group * getPagsPerGroup() + i];
405
                return null;
406
        }
407
        
408
        /**
409
         * Obtiene la p?gina de datos del grupo definido en el par?metro group y de la 
410
         * posici?n pag dentro de ese grupo.
411
         * @param group Grupo de la p?gina requerida
412
         * @param pag N?mero de p?gina dentro del grupo
413
         * @return PageBuffer correspondiente a la p?gina recuperada
414
         */
415
        public PageBuffer getPageBuffer(int group, int posInGroup) {
416
                return page[group * getPagsPerGroup() + posInGroup];
417
        }
418
        
419
        /**
420
         * Obtiene la p?gina de datos actualmente accedida
421
         * @return PageBuffer correspondiente a la p?gina que se est? accediendo
422
         */
423
        public PageBuffer getAccessPage() {
424
                return accessPage;
425
        }
426
        
427
        /**
428
         * Asigna el buffer de la p?gina accedida por referencia
429
         * @param pb
430
         */
431
        public void setAccessPage(PageBuffer pb, int pagNumber){
432
                accessPage = pb;
433
                numberInAccessPage = pagNumber;
434
        }
435
        
436
        /**
437
         * Consulta si una p?gina de cach? ha sido modificada desde que se carg? en cach? o no.
438
         * @param nCachePag N?mero de p?gina de cach? (posici?n de esta)
439
         * @return true si ha sido modificada y false si no lo ha sido.
440
         */
441
        public boolean isModified(int nCachePag){
442
                return modified[nCachePag];
443
        }
444

    
445
        /**
446
         * Consulta si una p?gina de cach? ha sido modificada desde que se carg? en cach? o no.
447
         * @param group Grupo en el que se encuentra la p?gina
448
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
449
         * @return true si ha sido modificada y false si no lo ha sido.
450
         */
451
        public boolean isModified(int group, int posInGroup){
452
                return modified[group * getPagsPerGroup() + posInGroup];
453
        }
454

    
455
        /**
456
         * Pone como modificada una p?gina de cach?
457
         * @param nCachePag N?mero de p?gina de cach? (posici?n de esta)
458
         */
459
        public void setModify(int nCachePag){
460
                modified[nCachePag] = true;        
461
        }
462
        
463
        /**
464
         * Pone como modificada una p?gina de cach?
465
         * @param group Grupo en el que se encuentra la p?gina
466
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
467
         */
468
        public void setModify(int group, int posInGroup){
469
                modified[group * getPagsPerGroup() + posInGroup] = true;        
470
        }
471
        
472
        /**
473
         * Pone como no modificada una p?gina de cach?
474
         * @param nCachePag N?mero de p?gina de cach? (posici?n de esta)
475
         */
476
        public void unsetModify(int nCachePag){
477
                modified[nCachePag] = false;        
478
        }
479
        
480
        /**
481
         * Pone como no modificada una p?gina de cach?
482
         * @param group Grupo en el que se encuentra la p?gina
483
         * @param posInGroup Posici?n dentro del grupo en el que est? la p?gina
484
         */
485
        public void unsetModify(int group, int posInGroup){
486
                modified[group * getPagsPerGroup() + posInGroup] = false;        
487
        }
488
        
489
        /**
490
         * Obtiene el n?mero de p?ginas de la cach?
491
         * @return N?mero total de p?ginas de la cach?
492
         */
493
        public int getNPags() {
494
                return cacheStruct.getNPags();
495
        }
496
        
497
        /**
498
         * Obtiene el n?mero de bandas
499
         * @return N?mero de bandas
500
         */
501
        public int getNBands() {
502
                return cacheStruct.getNBands();
503
        }
504
        
505
        /**
506
         * Obtiene la estructura de ca cach?
507
         * @return CacheStruct
508
         */
509
        public CacheStruct getCacheStruct() {
510
                return cacheStruct;
511
        }
512
        
513
        /**
514
         * Obtiene el n?mero de grupos de cach?
515
         * @return N?mero de grupos
516
         */
517
        public int getNGroups() {
518
                return cacheStruct.getNGroups();
519
        }
520
        
521
        /**
522
         * Obtiene el n?mero total de p?ginas del raster
523
         * @return N?mero total de p?ginas
524
         */
525
        public int getNTotalPags() {
526
                return cacheStruct.getNTotalPags();
527
        }
528
        
529
        /**
530
         * Obtiene el array con los n?meros de p?gina que hay cargados
531
         * en cada bloque de cache
532
         * @return array con los n?mero de p?gina
533
         */
534
        public int[] getPageNumberInCache(){
535
                return this.pageNumberInCache;
536
        }
537
        
538
        /**
539
         * Para extraer el desplazamiento de una direcci?n (l?nea de raster) hay que hacer una operaci?n And con 
540
         * con la altura de la p?gina -1. Por ejemplo, una p?gina de 16 l?neas de altura el desplazamiento ser?
541
         * 16 - 1 = 15 porque 15 en binario es 1111.
542
         * 
543
         * Si queremos acceder a la linea del raster n?mero 83 (1010011) realizando la operaci?n And con el valor del
544
         * desplazamiento obtenemos (0001111 & 1010011 = 0000011), es decir el valor 3 en decimal. Esto quiere decir
545
         * que la l?nea 83 del raster es la 3 de su p?gina. 
546
         * @return valor del desplazamiento
547
         */
548
        public int getOffset() {
549
                return cacheStruct.getOffset();
550
        }
551
        
552
        /**
553
         * Convierte una p?gina dentro de un grupo de la cach? en un n?mero de 
554
         * p?gina de cach?. Por ejemplo, en una cach? de 10 grupos y 5 p?ginas por grupo
555
         * la p?gina 2 del grupo 4 devolver? el 23 (5 * 4 + 3 = 23) teniendo en cuenta que
556
         * la p?gina y el grupo cero tambi?n cuentan.  
557
         * @param group
558
         * @param pageInGroup
559
         * @return
560
         */
561
        public int convertPageInGroupToPageInCache(int group, int pageInGroup){
562
                return (group * cacheStruct.getPagsPerGroup() + pageInGroup);
563
        }
564

    
565
        /**
566
         * Actualiza los ?ltimos accesos del grupo pasado por par?metro. Se incrementar? 
567
         * uno en todas las p?ginas del conjunto a excepci?n de las que valen -1 ya que 
568
         * esto significa que no hay p?gina cargada en dicha posici?n.
569
         * @param group N?mero de grupo a actualizar sus accesos
570
         * @return La posici?n del elemento del grupo con valor m?ximo. Este elemento 
571
         * es el candidato para el reemplazo.
572
         */
573
        public int updateLastAccess(int group){
574
                int max = Integer.MIN_VALUE;
575
                int posMax = 0;
576
                for(int i = 0; i < getPagsPerGroup(); i++){
577
                        if(getLastAccess()[group][i] >= 0)
578
                                getLastAccess()[group][i] ++;
579
                        
580
                        if(getLastAccess()[group][i] > max){
581
                                max = getLastAccess()[group][i];
582
                                posMax = i;
583
                        }
584
                }
585
                return posMax;
586
        }
587
        
588
        /**
589
         * Obtiene la posici?n del grupo de la p?gina a reemplazar, es decir la de m?ximo valor
590
         * en el vector lastAccess.
591
         * @param group N?mero de grupo a obtener la p?gina de reemplazo
592
         * @return La posici?n del elemento del grupo con valor m?ximo. Este elemento 
593
         * es el candidato para el reemplazo.
594
         */
595
        public int posInGroupPagToReplace(int group){
596
                int max = Integer.MIN_VALUE;
597
                int posMax = 0;
598
                for(int i = 0; i < getPagsPerGroup(); i++){
599
                        if(getLastAccess()[group][i] > max){
600
                                max = getLastAccess()[group][i];
601
                                posMax = i;
602
                        }
603
                }
604
                return posMax;
605
        } 
606
        
607
        /**
608
         * Carga una p?gina especificada en el par?metro nPag con los datos necesarios. La
609
         * petici?n que ha de hacerse se calcula previamente con la estructura de la cach?.
610
         *   
611
         * @param group Grupo sobre el que se carga la p?gina nPag
612
         * @param posInGroupPageToReplace Posici?n dentro del grupo sobre el que se carga la p?gina
613
         * @param nPag P?gina a cargar
614
         */
615
        public void loadPage(int group, int posInGroupPageToReplace, int nPag){
616
                page[group * getPagsPerGroup() + posInGroupPageToReplace].loadPage(nPag);
617
        }
618
        
619
        /**
620
         * Salva una p?gina especificada en el par?metro nPag a disco. La
621
         * petici?n que ha de hacerse se calcula previamente con la estructura de la cach?.
622
         *   
623
         * @param group Grupo del que se salva la p?gina nPag
624
         * @param posInGroupPageToReplace Posici?n dentro del grupo del que se salva la p?gina
625
         * @param nPag P?gina a salvar
626
         * @throws IOException
627
         */
628
        public void savePage(int group, int posInGroupPageToReplace, int nPag) throws IOException {
629
                page[group * getPagsPerGroup() + posInGroupPageToReplace].savePage(nPag);
630
        }
631

    
632
        /**
633
         * Salva a disco todas las p?ginas en memoria cach? e inicializa estructuras de datos.
634
         * 
635
         * @throws IOException
636
         */
637
        public void resetCache() throws IOException {
638
                for (int iCachePage = 0; iCachePage < page.length; iCachePage++){ 
639
                        if(modified[iCachePage])
640
                                page[iCachePage].savePage(this.getRasterPageNumberInPosition(iCachePage));
641
                }
642
                initStructs();
643
        }
644
        
645
        /**
646
         * Elimina una banda de la cach?. Antes salva a disco todos los trozos cacheados e inicializa
647
         * las estructuras de control de cach?. 
648
         * @param nBand N?mero de banda a eliminar
649
         * @throws IOException 
650
         */
651
        public void deleteBand(int nBand) throws IOException {
652
                resetCache();
653
                for (int iPage = 0; iPage < hddPage.length; iPage++)
654
                        hddPage[iPage].deleteBand(nBand);
655
        }
656
        
657
        /**
658
         * Asigna una banda de disco a todas las p?ginas.
659
         * @param cacheDataSource Fuente de las p?ginas. Es la referencia a disco de ellas.
660
         * @throws IOException 
661
         */
662
        public void assignBand(int nBand, ICacheDataSource[] cacheDataSource) throws IOException {
663
                resetCache();
664
                for (int iPage = 0; iPage < hddPage.length; iPage++)
665
                        hddPage[iPage].assignBand(nBand, cacheDataSource[iPage]);
666
        }
667
        
668
        /**
669
         * Obtiene la fuente de datos de una banda de una p?gina de disco.
670
         * @param nPage P?gina de la que se quiere la banda
671
         * @param nBand Banda de la que se quiere la fuente de datos
672
         * @return HddPage
673
         */
674
        public ICacheDataSource getHddPage(int nPage, int nBand) {
675
                return hddPage[nPage].getBandDataSource(nBand);
676
        }
677
        
678
        /**
679
         * Consulta si alguna p?gina de memoria tiene modificaciones para volcar a disco
680
         * @return true si hay alguna p?gina con modificaciones y false si no la hay
681
         */
682
        public boolean anyPageModified(){
683
                for (int iPage = 0; iPage < modified.length; iPage++) {
684
                        if(modified[iPage])
685
                                return true;
686
                }
687
                return false;
688
        }
689
        
690
        /**
691
         * Imprime la informaci?n de estructura de cach?
692
         */
693
        public void show() {
694
                cacheStruct.show();
695
                System.out.println("Cacheada:");
696
                for(int i = 0; i < cacheada.length; i++)
697
                        System.out.print(i + "=" + cacheada[i]+" ");
698
                System.out.println();
699
                System.out.println("LastAccess:");
700
                for(int i = 0; i < cacheStruct.getNGroups(); i++){
701
                        System.out.println("Grupo " + i +":");
702
                        for(int j = 0; j < cacheStruct.getPagsPerGroup(); j++)
703
                                System.out.println("elem " + j + " : " + "Page " + pageNumberInCache[i * cacheStruct.getPagsPerGroup() + j] + " : " + lastAccess[i][j]);
704
                
705
                }
706
        }
707
        
708
}