Update cache for Java 8

This commit is contained in:
Jikoo 2020-03-15 09:49:11 -04:00
parent 1cc36d08bd
commit 8bc389496b
4 changed files with 40 additions and 84 deletions

View file

@ -19,11 +19,12 @@ package com.lishid.openinv.util;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap; import com.google.common.collect.TreeMultimap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
/** /**
* A minimal thread-safe time-based cache implementation backed by a HashMap and TreeMultimap. * A minimal thread-safe time-based cache implementation backed by a HashMap and TreeMultimap.
@ -35,7 +36,7 @@ public class Cache<K, V> {
private final Map<K, V> internal; private final Map<K, V> internal;
private final Multimap<Long, K> expiry; private final Multimap<Long, K> expiry;
private final long retention; private final long retention;
private final Function<V> inUseCheck, postRemoval; private final Function<V, Boolean> inUseCheck, postRemoval;
/** /**
* Constructs a Cache with the specified retention duration, in use function, and post-removal function. * Constructs a Cache with the specified retention duration, in use function, and post-removal function.
@ -44,21 +45,10 @@ public class Cache<K, V> {
* @param inUseCheck Function used to check if a key is considered in use * @param inUseCheck Function used to check if a key is considered in use
* @param postRemoval Function used to perform any operations required when a key is invalidated * @param postRemoval Function used to perform any operations required when a key is invalidated
*/ */
public Cache(final long retention, final Function<V> inUseCheck, final Function<V> postRemoval) { public Cache(final long retention, final Function<V, Boolean> inUseCheck, final Function<V, Boolean> postRemoval) {
this.internal = new HashMap<K, V>(); this.internal = new HashMap<>();
this.expiry = TreeMultimap.create(new Comparator<Long>() { this.expiry = TreeMultimap.create(Long::compareTo, (k1, k2) -> Objects.equals(k1, k2) ? 0 : 1);
@Override
public int compare(final Long long1, final Long long2) {
return long1.compareTo(long2);
}
},
new Comparator<K>() {
@Override
public int compare(final K k1, final K k2) {
return k1 == k2 || k1 != null && k1.equals(k2) ? 0 : 1;
}
});
this.retention = retention; this.retention = retention;
this.inUseCheck = inUseCheck; this.inUseCheck = inUseCheck;
@ -146,7 +136,7 @@ public class Cache<K, V> {
public void invalidateAll() { public void invalidateAll() {
synchronized (this.internal) { synchronized (this.internal) {
for (V value : this.internal.values()) { for (V value : this.internal.values()) {
this.postRemoval.run(value); this.postRemoval.apply(value);
} }
this.expiry.clear(); this.expiry.clear();
this.internal.clear(); this.internal.clear();
@ -160,7 +150,7 @@ public class Cache<K, V> {
private void lazyCheck() { private void lazyCheck() {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
synchronized (this.internal) { synchronized (this.internal) {
List<K> inUse = new ArrayList<K>(); List<K> inUse = new ArrayList<>();
for (Iterator<Map.Entry<Long, K>> iterator = this.expiry.entries().iterator(); iterator for (Iterator<Map.Entry<Long, K>> iterator = this.expiry.entries().iterator(); iterator
.hasNext();) { .hasNext();) {
Map.Entry<Long, K> entry = iterator.next(); Map.Entry<Long, K> entry = iterator.next();
@ -171,7 +161,7 @@ public class Cache<K, V> {
iterator.remove(); iterator.remove();
if (this.inUseCheck.run(this.internal.get(entry.getValue()))) { if (this.inUseCheck.apply(this.internal.get(entry.getValue()))) {
inUse.add(entry.getValue()); inUse.add(entry.getValue());
continue; continue;
} }
@ -182,7 +172,7 @@ public class Cache<K, V> {
continue; continue;
} }
this.postRemoval.run(value); this.postRemoval.apply(value);
} }
long nextExpiry = now + this.retention; long nextExpiry = now + this.retention;

View file

@ -1,28 +0,0 @@
/*
* Copyright (C) 2011-2020 lishid. All rights reserved.
*
* This program 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, version 3.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.util;
/**
* Abstraction for some simple cache calls.
*
* @author Jikoo
*/
public abstract class Function<V> {
public abstract boolean run(V value);
}

View file

@ -70,47 +70,41 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
private final Multimap<String, Class<? extends Plugin>> pluginUsage = HashMultimap.create(); private final Multimap<String, Class<? extends Plugin>> pluginUsage = HashMultimap.create();
private final Cache<String, Player> playerCache = new Cache<>(300000L, private final Cache<String, Player> playerCache = new Cache<>(300000L,
new Function<Player>() { value -> {
@Override String key = OpenInv.this.getPlayerID(value);
public boolean run(final Player value) {
String key = OpenInv.this.getPlayerID(value); return OpenInv.this.inventories.containsKey(key)
return OpenInv.this.inventories.containsKey(key) && OpenInv.this.inventories.get(key).isInUse()
&& OpenInv.this.inventories.get(key).isInUse() || OpenInv.this.enderChests.containsKey(key)
|| OpenInv.this.enderChests.containsKey(key) && OpenInv.this.enderChests.get(key).isInUse()
&& OpenInv.this.enderChests.get(key).isInUse() || OpenInv.this.pluginUsage.containsKey(key);
|| OpenInv.this.pluginUsage.containsKey(key); },
value -> {
String key = OpenInv.this.getPlayerID(value);
// Check if inventory is stored, and if it is, remove it and eject all viewers
if (OpenInv.this.inventories.containsKey(key)) {
Inventory inv = OpenInv.this.inventories.remove(key).getBukkitInventory();
List<HumanEntity> viewers = inv.getViewers();
for (HumanEntity entity : viewers.toArray(new HumanEntity[0])) {
entity.closeInventory();
}
} }
}, new Function<Player>() {
@Override
public boolean run(final Player value) {
String key = OpenInv.this.getPlayerID(value); // Check if ender chest is stored, and if it is, remove it and eject all viewers
if (OpenInv.this.enderChests.containsKey(key)) {
// Check if inventory is stored, and if it is, remove it and eject all viewers Inventory inv = OpenInv.this.enderChests.remove(key).getBukkitInventory();
if (OpenInv.this.inventories.containsKey(key)) { List<HumanEntity> viewers = inv.getViewers();
Inventory inv = OpenInv.this.inventories.remove(key).getBukkitInventory(); for (HumanEntity entity : viewers.toArray(new HumanEntity[0])) {
List<HumanEntity> viewers = inv.getViewers(); entity.closeInventory();
for (HumanEntity entity : viewers.toArray(new HumanEntity[0])) { }
entity.closeInventory();
} }
}
// Check if ender chest is stored, and if it is, remove it and eject all viewers if (!OpenInv.this.disableSaving() && !value.isOnline()) {
if (OpenInv.this.enderChests.containsKey(key)) { value.saveData();
Inventory inv = OpenInv.this.enderChests.remove(key).getBukkitInventory();
List<HumanEntity> viewers = inv.getViewers();
for (HumanEntity entity : viewers.toArray(new HumanEntity[0])) {
entity.closeInventory();
} }
} return true;
});
if (!OpenInv.this.disableSaving() && !value.isOnline()) {
value.saveData();
}
return true;
}
});
private InternalAccessor accessor; private InternalAccessor accessor;

View file

@ -89,7 +89,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version> <version>3.2.2</version>
<configuration> <configuration>
<filters> <filters>
<filter> <filter>