1
1
package github .nighter .smartspawner .spawner .properties ;
2
2
3
3
import org .bukkit .inventory .ItemStack ;
4
+ import org .bukkit .inventory .meta .ItemMeta ;
5
+
4
6
import java .util .*;
5
7
import java .util .concurrent .ConcurrentHashMap ;
6
8
@@ -19,6 +21,16 @@ public class VirtualInventory {
19
21
private static final Comparator <Map .Entry <ItemSignature , Long >> ITEM_COMPARATOR =
20
22
Comparator .comparing (e -> e .getKey ().getTemplateRef ().getType ().name ());
21
23
24
+ // Add an LRU cache for expensive item operations
25
+ private static final int ITEM_CACHE_SIZE = 128 ;
26
+ private static final Map <ItemStack , ItemSignature > signatureCache =
27
+ Collections .synchronizedMap (new LinkedHashMap <ItemStack , ItemSignature >(ITEM_CACHE_SIZE , 0.75f , true ) {
28
+ @ Override
29
+ protected boolean removeEldestEntry (Map .Entry <ItemStack , ItemSignature > eldest ) {
30
+ return size () > ITEM_CACHE_SIZE ;
31
+ }
32
+ });
33
+
22
34
public VirtualInventory (int maxSlots ) {
23
35
this .maxSlots = maxSlots ;
24
36
this .consolidatedItems = new ConcurrentHashMap <>();
@@ -43,19 +55,49 @@ public ItemSignature(ItemStack item) {
43
55
this .hashCode = calculateHashCode ();
44
56
}
45
57
58
+ // Replace the current calculateHashCode() method with:
46
59
private int calculateHashCode () {
47
- return Objects .hash (
48
- template .getType (),
49
- template .getDurability (),
50
- template .getItemMeta () != null ? template .getItemMeta ().toString () : null
51
- );
60
+ // Use a faster hash algorithm and cache more item properties
61
+ int result = 31 * template .getType ().ordinal (); // Using ordinal() instead of name() hashing
62
+ result = 31 * result + (int )template .getDurability ();
63
+
64
+ // Only access ItemMeta when needed
65
+ if (template .hasItemMeta ()) {
66
+ ItemMeta meta = template .getItemMeta ();
67
+ // Extract only the essential meta properties that determine similarity
68
+ result = 31 * result + (meta .hasDisplayName () ? meta .getDisplayName ().hashCode () : 0 );
69
+ result = 31 * result + (meta .hasLore () ? meta .getLore ().hashCode () : 0 );
70
+ result = 31 * result + (meta .hasEnchants () ? meta .getEnchants ().hashCode () : 0 );
71
+ }
72
+ return result ;
52
73
}
53
74
54
75
@ Override
55
76
public boolean equals (Object o ) {
56
77
if (this == o ) return true ;
57
78
if (!(o instanceof ItemSignature )) return false ;
58
79
ItemSignature that = (ItemSignature ) o ;
80
+
81
+ // First compare cheap properties
82
+ if (template .getType () != that .template .getType () ||
83
+ template .getDurability () != that .template .getDurability ()) {
84
+ return false ;
85
+ }
86
+
87
+ // Only check ItemMeta if types match
88
+ boolean thisHasMeta = template .hasItemMeta ();
89
+ boolean thatHasMeta = that .template .hasItemMeta ();
90
+
91
+ if (thisHasMeta != thatHasMeta ) {
92
+ return false ;
93
+ }
94
+
95
+ // If both have no meta, they're similar enough
96
+ if (!thisHasMeta ) {
97
+ return true ;
98
+ }
99
+
100
+ // For complex items, fall back to isSimilar but only as a last resort
59
101
return template .isSimilar (that .template );
60
102
}
61
103
@@ -79,27 +121,43 @@ public String getMaterialName() {
79
121
}
80
122
}
81
123
124
+ public static ItemSignature getSignature (ItemStack item ) {
125
+ // First try to get from cache
126
+ ItemSignature cachedSig = signatureCache .get (item );
127
+ if (cachedSig != null ) {
128
+ return cachedSig ;
129
+ }
130
+
131
+ // Create new signature and cache it
132
+ ItemSignature newSig = new ItemSignature (item );
133
+ signatureCache .put (item .clone (), newSig );
134
+ return newSig ;
135
+ }
136
+
82
137
// Add items in bulk with minimal operations
83
138
public void addItems (List <ItemStack > items ) {
84
139
if (items .isEmpty ()) return ;
85
140
86
- // Process items in a single batch
87
- boolean updated = false ;
141
+ // Pre-allocate space for batch processing
142
+ Map <ItemSignature , Long > itemBatch = new HashMap <>(items .size ());
143
+
144
+ // Consolidate all items first
88
145
for (ItemStack item : items ) {
89
146
if (item == null || item .getAmount () <= 0 ) continue ;
90
-
91
- ItemSignature sig = new ItemSignature (item );
92
- consolidatedItems .merge (sig , (long ) item .getAmount (), Long ::sum );
93
- updated = true ;
147
+ ItemSignature sig = getSignature (item ); // Use cached signature
148
+ itemBatch .merge (sig , (long ) item .getAmount (), Long ::sum );
94
149
}
95
150
96
- if (updated ) {
151
+ // Apply all changes in one operation
152
+ if (!itemBatch .isEmpty ()) {
153
+ for (Map .Entry <ItemSignature , Long > entry : itemBatch .entrySet ()) {
154
+ consolidatedItems .merge (entry .getKey (), entry .getValue (), Long ::sum );
155
+ }
97
156
displayCacheDirty = true ;
98
157
metricsCacheDirty = true ;
99
- sortedEntriesCache = null ; // Invalidate sorted entries cache
158
+ sortedEntriesCache = null ;
100
159
}
101
160
}
102
-
103
161
// Remove items in bulk with minimal operations
104
162
public boolean removeItems (List <ItemStack > items ) {
105
163
if (items .isEmpty ()) return true ;
0 commit comments