@@ -15,7 +15,7 @@ public class ANNIndex implements AnnoyIndex {
1515
1616
1717 private final ArrayList <Long > roots ;
18- private Map < Integer , MappedByteBuffer > buffers = new HashMap <>() ;
18+ private MappedByteBuffer [] buffers ;
1919
2020 private final int DIMENSION , MIN_LEAF_SIZE ;
2121 private final IndexType INDEX_TYPE ;
@@ -72,20 +72,25 @@ public ANNIndex(final int dimension,
7272 private void load (final String filename ) throws IOException {
7373 memoryMappedFile = new RandomAccessFile (filename , "r" );
7474 long fileSize = memoryMappedFile .length ();
75- int buffIndex = (int ) Math .ceil (((double ) fileSize ) / BLOCK_SIZE ) - 1 ;
75+ if (fileSize == 0L ) {
76+ throw new IOException ("Index is a 0-byte file?" );
77+ }
78+
79+ int buffIndex = (int ) (fileSize - 1 ) / BLOCK_SIZE ;
7680 int rest = (int ) (fileSize % BLOCK_SIZE );
7781 int blockSize = (rest > 0 ? rest : BLOCK_SIZE );
7882 long position = Math .max (0 , fileSize - blockSize );
7983
84+ buffers = new MappedByteBuffer [buffIndex + 1 ];
8085 boolean process = true ;
8186 int m = -1 ;
8287 long index = fileSize ;
83- while (blockSize > 0 ) {
88+ while (position >= 0 ) {
8489 MappedByteBuffer annBuf = memoryMappedFile .getChannel ().map (
8590 FileChannel .MapMode .READ_ONLY , position , blockSize );
8691 annBuf .order (ByteOrder .LITTLE_ENDIAN );
8792
88- buffers . put ( buffIndex --, annBuf ) ;
93+ buffers [ buffIndex --] = annBuf ;
8994
9095 for (int i = blockSize - NODE_SIZE ; process && i >= 0 ; i -= NODE_SIZE ) {
9196 index -= NODE_SIZE ;
@@ -95,31 +100,31 @@ private void load(final String filename) throws IOException {
95100 m = k ;
96101 } else {
97102 process = false ;
98- break ;
99103 }
100104 }
101- blockSize = ( int ) Math . min ( BLOCK_SIZE , position ) ;
105+ blockSize = BLOCK_SIZE ;
102106 position = position - blockSize ;
103107 }
104108 }
105109
106110 private float getFloatInAnnBuf (long pos ) {
107- int b = (int ) Math . floor ((( double ) pos ) / BLOCK_SIZE ) ;
108- int f = (int ) ( pos - ( b * BLOCK_SIZE )) ;
109- return buffers . get ( b ) .getFloat (f );
111+ int b = (int ) pos / BLOCK_SIZE ;
112+ int f = (int ) pos % BLOCK_SIZE ;
113+ return buffers [ b ] .getFloat (f );
110114 }
111115
112116 private int getIntInAnnBuf (long pos ) {
113- int b = (int ) Math . floor ((( double ) pos ) / BLOCK_SIZE ) ;
114- int f = (int ) ( pos - ( b * BLOCK_SIZE )) ;
115- return buffers . get ( b ) .getInt (f );
117+ int b = (int ) pos / BLOCK_SIZE ;
118+ int i = (int ) pos % BLOCK_SIZE ;
119+ return buffers [ b ] .getInt (i );
116120 }
117121
118122 @ Override
119123 public void getNodeVector (final long nodeOffset , float [] v ) {
124+ MappedByteBuffer nodeBuf = buffers [(int ) nodeOffset / BLOCK_SIZE ];
125+ int offset = (int ) (nodeOffset % BLOCK_SIZE ) + K_NODE_HEADER_STYLE ;
120126 for (int i = 0 ; i < DIMENSION ; i ++) {
121- long offSet = nodeOffset + K_NODE_HEADER_STYLE + i * FLOAT_SIZE ;
122- v [i ] = getFloatInAnnBuf (offSet );
127+ v [i ] = nodeBuf .getFloat (offset + i * FLOAT_SIZE );
123128 }
124129 }
125130
0 commit comments