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); }
/// <summary> /// 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. /// </summary> /// <param name="subFileParameter"> /// the parameters of the map file for which the index entry is needed. </param> /// <param name="blockNumber"> /// the number of the block in the map file. </param> /// <returns> the index entry. </returns> /// <exception cref="IOException"> /// if an I/O error occurs during reading. </exception> internal virtual 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 = this.map.Get(indexCacheEntryKey); if (indexBlock == null) { // 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.randomAccessFile.Seek(indexBlockPosition, SeekOrigin.Begin); if (this.randomAccessFile.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.BYTES_PER_INDEX_ENTRY); // return the real index entry return(Deserializer.GetFiveBytesLong((sbyte[])(Array)indexBlock, addressInIndexBlock)); }