Coverage Summary for Class: LRUCache (com.kotlinorm.utils)

Class Method, % Branch, % Line, % Instruction, %
LRUCache 100% (6/6) 88.9% (16/18) 93.3% (42/45) 91.8% (234/255)
LRUCache$Companion
LRUCache$Node 100% (3/3) 100% (3/3) 100% (38/38)
Total 100% (9/9) 88.9% (16/18) 93.8% (45/48) 92.8% (272/293)


 /**
  * Copyright 2022-2025 kronos-orm
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package com.kotlinorm.utils
 
 class LRUCache<T, R>(private val capacity: Int = DEFAULT_LRU_CACHE_CAPACITY, val defaultValue: ((T) -> R?)? = null) {
 
     private val map = hashMapOf<T, Node<T, R>>()
     private val head: Node<T, R> = Node()
     private val tail: Node<T, R> = Node()
 
     init {
         head.next = tail
         tail.prev = head
     }
 
     operator fun get(key: T): R? {
         if (map.containsKey(key)) {
             val node = map[key]!!
             remove(node)
             addAtEnd(node)
             if (node.value != null)
                 return node.value
         }
         if (defaultValue != null) {
             if (defaultValue(key) == null) {
                 return null
             } else {
                 val node = Node(key, defaultValue(key))
                 addAtEnd(node)
                 map[key] = node
                 if (map.size > capacity) {
                     val first = head.next!!
                     remove(first)
                     map.remove(first.key)
                 }
                 return node.value!!
             }
         } else {
             return null
         }
     }
 
     operator fun get(key: T, defaultValue: ((T) -> R?)): R {
         return get(key) ?: defaultValue(key) ?: throw IllegalStateException("default value not found")
     }
 
     operator fun set(key: T, value: R) {
         if (map.containsKey(key)) {
             remove(map[key]!!)
         }
         val node = Node(key, value)
         addAtEnd(node)
         map[key] = node
         if (map.size > capacity) {
             val first = head.next!!
             remove(first)
             map.remove(first.key)
         }
     }
 
     private fun remove(node: Node<T, R>) {
         val next = node.next!!
         val prev = node.prev!!
         prev.next = next
         next.prev = prev
     }
 
     private fun addAtEnd(node: Node<T, R>) {
         val prev = tail.prev!!
         prev.next = node
         node.prev = prev
         node.next = tail
         tail.prev = node
     }
 
     data class Node<T, R>(val key: T? = null, val value: R? = null) {
         var next: Node<T, R>? = null
         var prev: Node<T, R>? = null
     }
 
     companion object{
         const val DEFAULT_LRU_CACHE_CAPACITY = 128
     }
 }