rajinisivaram commented on a change in pull request #9275: URL: https://github.com/apache/kafka/pull/9275#discussion_r488833309
########## File path: core/src/main/scala/kafka/server/epoch/LeaderEpochFileCache.scala ########## @@ -47,63 +47,81 @@ class LeaderEpochFileCache(topicPartition: TopicPartition, private val epochs = new util.TreeMap[Int, EpochEntry]() inWriteLock(lock) { - checkpoint.read().foreach { entry => - epochs.put(entry.epoch, entry) - } + checkpoint.read().foreach(assign) } /** * Assigns the supplied Leader Epoch to the supplied Offset * Once the epoch is assigned it cannot be reassigned */ def assign(epoch: Int, startOffset: Long): Unit = { - inWriteLock(lock) { - val updateNeeded = if (epochs.isEmpty) { - true - } else { - val lastEntry = epochs.lastEntry.getValue - lastEntry.epoch != epoch || startOffset < lastEntry.startOffset - } + val entry = EpochEntry(epoch, startOffset) + if (assign(entry)) { + debug(s"Appended new epoch entry $entry. Cache now contains ${epochs.size} entries.") + flush() + } + } - if (updateNeeded) { - truncateAndAppend(EpochEntry(epoch, startOffset)) - flush() + private def assign(entry: EpochEntry): Boolean = { + if (entry.epoch < 0 || entry.startOffset < 0) { + throw new IllegalArgumentException(s"Received invalid partition leader epoch entry $entry") + } + + // Check whether the append is needed before acquiring the write lock + // in order to avoid contention with readers in the common case + latestEntry.foreach { lastEntry => + if (entry.epoch == lastEntry.epoch && entry.startOffset >= lastEntry.startOffset) { + return false Review comment: Do we need to check again inside the lock before update because this is outside the lock? ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org