diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/util/LRUCache.java b/ultrasonic/src/main/java/org/moire/ultrasonic/util/LRUCache.java
deleted file mode 100644
index 2adc7cea..00000000
--- a/ultrasonic/src/main/java/org/moire/ultrasonic/util/LRUCache.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see .
-
- Copyright 2009 (C) Sindre Mehus
- */
-package org.moire.ultrasonic.util;
-
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Sindre Mehus
- */
-public class LRUCache
-{
-
- private final int capacity;
- private final Map map;
-
- public LRUCache(int capacity)
- {
- map = new HashMap(capacity);
- this.capacity = capacity;
- }
-
- public synchronized V get(K key)
- {
- TimestampedValue value = map.get(key);
-
- V result = null;
- if (value != null)
- {
- value.updateTimestamp();
- result = value.getValue();
- }
-
- return result;
- }
-
- public synchronized void put(K key, V value)
- {
- if (map.size() >= capacity)
- {
- removeOldest();
- }
- map.put(key, new TimestampedValue(value));
- }
-
- public void clear()
- {
- map.clear();
- }
-
- private void removeOldest()
- {
- K oldestKey = null;
- long oldestTimestamp = Long.MAX_VALUE;
-
- for (Map.Entry entry : map.entrySet())
- {
- K key = entry.getKey();
- TimestampedValue value = entry.getValue();
- if (value.getTimestamp() < oldestTimestamp)
- {
- oldestTimestamp = value.getTimestamp();
- oldestKey = key;
- }
- }
-
- if (oldestKey != null)
- {
- map.remove(oldestKey);
- }
- }
-
- private final class TimestampedValue
- {
-
- private final SoftReference value;
- private long timestamp;
-
- public TimestampedValue(V value)
- {
- this.value = new SoftReference(value);
- updateTimestamp();
- }
-
- public V getValue()
- {
- return value.get();
- }
-
- public long getTimestamp()
- {
- return timestamp;
- }
-
- public void updateTimestamp()
- {
- timestamp = System.currentTimeMillis();
- }
- }
-}
\ No newline at end of file
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LRUCache.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LRUCache.kt
new file mode 100644
index 00000000..22ab7f60
--- /dev/null
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/LRUCache.kt
@@ -0,0 +1,79 @@
+/*
+ * LRUCache.kt
+ * Copyright (C) 2009-2021 Ultrasonic developers
+ *
+ * Distributed under terms of the GNU GPLv3 license.
+ */
+package org.moire.ultrasonic.util
+
+import java.lang.ref.SoftReference
+import java.util.HashMap
+
+/**
+ * A cache that deletes the least-recently-used items.
+ */
+class LRUCache(capacity: Int) {
+ private val capacity: Int
+ private val map: MutableMap
+
+ @Synchronized
+ operator fun get(key: K): V? {
+ val value = map[key]
+ var result: V? = null
+ if (value != null) {
+ value.updateTimestamp()
+ result = value.getValue()
+ }
+ return result
+ }
+
+ @Synchronized
+ fun put(key: K, value: V) {
+ if (map.size >= capacity) {
+ removeOldest()
+ }
+ map[key] = TimestampedValue(value)
+ }
+
+ fun clear() {
+ map.clear()
+ }
+
+ private fun removeOldest() {
+ var oldestKey: K? = null
+ var oldestTimestamp = Long.MAX_VALUE
+ for ((key, value) in map) {
+ if (value.timestamp < oldestTimestamp) {
+ oldestTimestamp = value.timestamp
+ oldestKey = key
+ }
+ }
+ if (oldestKey != null) {
+ map.remove(oldestKey)
+ }
+ }
+
+ private inner class TimestampedValue(value: V) {
+ private val value: SoftReference = SoftReference(value)
+
+ var timestamp: Long = 0
+ private set
+
+ fun getValue(): V? {
+ return value.get()
+ }
+
+ fun updateTimestamp() {
+ timestamp = System.currentTimeMillis()
+ }
+
+ init {
+ updateTimestamp()
+ }
+ }
+
+ init {
+ map = HashMap(capacity)
+ this.capacity = capacity
+ }
+}