Log Segment read 方法源码解析
read方法执行流程图:
第一步:查找索引确定读取物理文件位置
val startOffsetAndSize = translateOffset(startOffset)
/**
* Find the physical file position for the first message with offset >= the requested offset. 查找偏移量>=请求的偏移量的第一条消息的物理文件位置。
*
* The startingFilePosition argument is an optimization that can be used if we already know a valid starting position in the file higher than the greatest-lower-bound from the index.
* startingFilePosition参数是一种优化,如果我们已经知道文件中一个有效的起始位置高于索引的最大下界,就可以使用它。
*
* @param offset The offset we want to translate 我们要转换的偏移量
* @param startingFilePosition A lower bound on the file position from which to begin the search. This is purely an optimization and when omitted, the search will begin at the position in the offset index.
* 开始搜索的文件位置的下界。这纯粹是一种优化,当省略时,搜索将从偏移索引中的位置开始。
* @return The position in the log storing the message with the least offset >= the requested offset and the size of the message or null if no message meets this criteria.
* 日志中存储具有最小偏移量的消息的位置>=请求的偏移量和消息大小,如果没有消息满足此条件,则为null。
*/
@threadsafe
private[log] def translateOffset(offset: Long, startingFilePosition: Int = 0): LogOffsetPosition = {
val mapping = offsetIndex.lookup(offset)
log.searchForOffsetWithSize(offset, max(mapping.position, startingFilePosition))
}
def offsetIndex: OffsetIndex = lazyOffsetIndex.get
/*
lazyOffsetIndex.scala
*/
def get: T = {
indexWrapper match {
case indexValue: IndexValue[T] => indexValue.index
case _: IndexFile =>
inLock(lock) {
indexWrapper match {
case indexValue: IndexValue[T] => indexValue.index
case indexFile: IndexFile =>
val indexValue = new IndexValue(loadIndex(indexFile.file))
indexWrapper = indexValue
indexValue.index
}
}
}
}
/**
offsetIndex.scala
* Find the largest offset less than or equal to the given targetOffset
and return a pair holding this offset and its corresponding physical file position.
* 查找小于或等于给定targetOffset的最大偏移量并返回一个包含该偏移量及其对应物理文件位置的对(pair)。
* @param targetOffset The offset to look up.
* @return The offset found and the corresponding file position for this offset
* If the target offset is smaller than the least entry in the index (or the index is empty),
* the pair (baseOffset, 0) is returned.
*/
def lookup(targetOffset: Long): OffsetPosition = {
maybeLock(lock) {
val idx = mmap.duplicate
val slot = largestLowerBoundSlotFor(idx, targetOffset, IndexSearchType.KEY)
if<