//此函數僅僅在upto已經是當前塊的結尾的時候方才調用來分配新塊。 public int allocSlice(final byte[] slice, final int upto) { //可根據塊的結束符來得到塊所在的層次。從而我們可以推斷,每個層次的塊都有不同的結束符,第1層為16,第2層位17,第3層18,依次類推。 final int level = slice[upto] & 15; //從數組總得到下一個層次及下一層塊的大小。 final int newLevel = nextLevelArray[level]; final int newSize = levelSizeArray[newLevel]; // 如果當前緩衝總量不夠大,則從DocumentsWriter的freeByteBlocks中分配。 if (byteUpto > DocumentsWriter.BYTE_BLOCK_SIZE-newSize) nextBuffer(); final int newUpto = byteUpto; final int offset = newUpto + byteOffset; byteUpto += newSize; //當分配了新的塊的時候,需要有一個指標從本塊指向下一個塊,使得讀取此資訊的時候,能夠在此塊讀取結束後,到下一個塊繼續讀取。 //這個指標需要4個byte,在本塊中,除了結束符所佔用的一個byte之外,之前的三個byte的資料都應該移到新的塊中,從而四個byte連起來形成一個指標。 buffer[newUpto] = slice[upto-3]; buffer[newUpto+1] = slice[upto-2]; buffer[newUpto+2] = slice[upto-1]; // 將位移量(也即指標)寫入到連同結束符在內的四個byte slice[upto-3] = (byte) (offset >>> 24); slice[upto-2] = (byte) (offset >>> 16); slice[upto-1] = (byte) (offset >>> 8); slice[upto] = (byte) offset; // 在新的塊的結尾寫入新的結束符,結束符和層次的關係就是(endbyte = 16 | level) buffer[byteUpto-1] = (byte) (16|newLevel); return newUpto+3; } |