public override bool Equals(Object obj) { if (this == obj) { return(true); } else if (!(obj is IndexCacheEntryKey)) { return(false); } IndexCacheEntryKey other = (IndexCacheEntryKey)obj; if (this.subFileParameter == null && other.subFileParameter != null) { return(false); } else if (this.subFileParameter != null && !this.subFileParameter.Equals(other.subFileParameter)) { return(false); } else if (this.indexBlockNumber != other.indexBlockNumber) { return(false); } return(true); }
/** * Returns the index entry of a block in the given map file. If the required index entry is not cached, it will be * read from the map file index and put in the cache. * * @param subFileParameter * the parameters of the map file for which the index entry is needed. * @param blockNumber * the number of the block in the map file. * @return the index entry. * @throws IOException * if an I/O error occurs during reading. */ public long getIndexEntry(SubFileParameter subFileParameter, long blockNumber) { // check if the block number is out of bounds if (blockNumber >= subFileParameter.NumberOfBlocks) { throw new IOException("invalid block number: " + blockNumber); } // calculate the index block number long indexBlockNumber = blockNumber / INDEX_ENTRIES_PER_BLOCK; // create the cache entry key for this request IndexCacheEntryKey indexCacheEntryKey = new IndexCacheEntryKey(subFileParameter, indexBlockNumber); // check for cached index block byte[] indexBlock; if (!this.map.TryGetValue(indexCacheEntryKey, out indexBlock)) { // cache miss, seek to the correct index block in the file and read it long indexBlockPosition = subFileParameter.IndexStartAddress + indexBlockNumber * SIZE_OF_INDEX_BLOCK; int remainingIndexSize = (int)(subFileParameter.IndexEndAddress - indexBlockPosition); int indexBlockSize = Math.Min(SIZE_OF_INDEX_BLOCK, remainingIndexSize); indexBlock = new byte[indexBlockSize]; this.Stream.Seek(indexBlockPosition, SeekOrigin.Begin); if (this.Stream.Read(indexBlock, 0, indexBlockSize) != indexBlockSize) { throw new IOException("could not read index block with size: " + indexBlockSize); } // put the index block in the map this.map.Add(indexCacheEntryKey, indexBlock); } // calculate the address of the index entry inside the index block long indexEntryInBlock = blockNumber % INDEX_ENTRIES_PER_BLOCK; int addressInIndexBlock = (int)(indexEntryInBlock * SubFileParameter.BytesPerIndexEntry); // return the real index entry return(Deserializer.GetLong(indexBlock, addressInIndexBlock, SubFileParameter.BytesPerIndexEntry)); }