File size: 2,376 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package net.minecraft.util;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicOps;
import net.minecraft.nbt.Tag;

public class EncoderCache {
    final LoadingCache<EncoderCache.Key<?, ?>, DataResult<?>> cache;

    public EncoderCache(int p_328135_) {
        this.cache = CacheBuilder.newBuilder()
            .maximumSize((long)p_328135_)
            .concurrencyLevel(1)
            .softValues()
            .build(new CacheLoader<EncoderCache.Key<?, ?>, DataResult<?>>() {
                public DataResult<?> load(EncoderCache.Key<?, ?> p_334212_) {
                    return p_334212_.resolve();
                }
            });
    }

    public <A> Codec<A> wrap(final Codec<A> p_332774_) {
        return new Codec<A>() {
            @Override
            public <T> DataResult<Pair<A, T>> decode(DynamicOps<T> p_335845_, T p_329817_) {
                return p_332774_.decode(p_335845_, p_329817_);
            }

            @Override
            public <T> DataResult<T> encode(A p_328409_, DynamicOps<T> p_330058_, T p_328392_) {
                return (DataResult<T>) EncoderCache.this.cache
                    .getUnchecked(new EncoderCache.Key<>(p_332774_, p_328409_, p_330058_))
                    .map(p_336406_ -> p_336406_ instanceof Tag tag ? tag.copy() : p_336406_);
            }
        };
    }

    static record Key<A, T>(Codec<A> codec, A value, DynamicOps<T> ops) {
        public DataResult<T> resolve() {
            return this.codec.encodeStart(this.ops, this.value);
        }

        @Override
        public boolean equals(Object p_334040_) {
            if (this == p_334040_) {
                return true;
            } else {
                return !(p_334040_ instanceof EncoderCache.Key<?, ?> key)
                    ? false
                    : this.codec == key.codec && this.value.equals(key.value) && this.ops.equals(key.ops);
            }
        }

        @Override
        public int hashCode() {
            int i = System.identityHashCode(this.codec);
            i = 31 * i + this.value.hashCode();
            return 31 * i + this.ops.hashCode();
        }
    }
}