2011-02-22 42 views
10

podría afirmarse en general: ¿cómo se implementa un método byte[] get(offset, length) para un archivo asignado en memoria que es más grande que 2 GB en Java.archivos de asignación más grandes de 2 GB con Java

con el contexto:

Estoy intentando leer de manera eficiente los archivos que son más grandes que 2 GB con al azar de E/S. Por supuesto, la idea es usar Java nio y API mapeada en memoria.

El problema viene con el límite de 2 GB para la asignación de memoria. Una de las soluciones sería mapear múltiples páginas de 2GB e indexar a través del desplazamiento.

Hay una solución similar aquí:

Binary search in a sorted (memory-mapped ?) file in Java

El problema de esta solución es que está diseñado para leer bytes mientras mi API se supone que leer byte[] (así que mi API sería algo así como read(offset, length)).

¿Sería simplemente trabajar para cambiar esa última get() a un get(offset, length)? ¿Qué sucede cuando el byte[] que estoy leyendo establece entre dos páginas?

Respuesta

4

No, mi respuesta a Binary search in a sorted (memory-mapped ?) no funcionaría para cambiar get() por get(offset, length) debido a la memoria del límite del conjunto de archivos mapeados, como sospecha. Puedo ver dos soluciones posibles:

  1. Superponga los archivos de la memoria asignada. Cuando lee, elija el archivo mapeado en memoria con el byte de inicio inmediatamente antes del byte de inicio de la lectura. Este enfoque no funcionará para lecturas mayores del 50% del tamaño máximo del mapa de memoria.
  2. Crea un método de creación de matriz de bytes que lee de dos diferentes dos archivos mapeados de memoria diferente. No estoy interesado en este enfoque ya que creo que algunas de las ganancias de rendimiento se perderán porque la matriz resultante no se mapeará en la memoria.
+1

¿Qué ganancias de rendimiento se perderán? Si devuelve un 'byte []', está copiando de la región 'mmap()' de todos modos. Llamar 'System.arraycopy' dos veces en vez de una vez en el mismo número total de bytes no es mucho peor. –

+0

@Scott Lamb: estoy de acuerdo en que el rendimiento alcanzado sería insignificante para esas condiciones de borde probablemente raras cuando 'get()' necesita leer de dos mapas diferentes en el algoritmo de "búsqueda binaria". Mi respuesta es que deberás codificarlo, de ahí las dos opciones. Solo agregar el desplazamiento sin ningún código nuevo detrás de 'get()' dará como resultado errores difíciles como el índice de errores fuera de límites. –

Cuestiones relacionadas