11package com .mageddo .dnsproxyserver .solver ;
22
3- import com .mageddo .commons .caching .LruTTLCache ;
3+ import com .github .benmanes .caffeine .cache .Cache ;
4+ import com .github .benmanes .caffeine .cache .Caffeine ;
5+ import com .github .benmanes .caffeine .cache .Expiry ;
46import com .mageddo .commons .lang .Objects ;
5- import com .mageddo .commons .lang .tuple .Pair ;
67import com .mageddo .dns .utils .Messages ;
78import com .mageddo .dnsproxyserver .solver .CacheName .Name ;
8- import lombok .RequiredArgsConstructor ;
9+ import lombok .Builder ;
10+ import lombok .Value ;
911import lombok .extern .slf4j .Slf4j ;
1012import org .xbill .DNS .Message ;
1113
1214import java .time .Duration ;
15+ import java .time .LocalDateTime ;
1316import java .util .HashMap ;
1417import java .util .HashSet ;
1518import java .util .Map ;
2023import static com .mageddo .dns .utils .Messages .findQuestionType ;
2124
2225@ Slf4j
23- @ RequiredArgsConstructor
2426public class SolverCache {
2527
26- private final LruTTLCache cache = new LruTTLCache (2048 , Duration .ofSeconds (5 ), false );
27-
2828 private final Name name ;
29+ private final Cache <String , CacheValue > cache ;
30+
31+ public SolverCache (Name name ) {
32+ this .name = name ;
33+ this .cache = Caffeine .newBuilder ()
34+ .maximumSize (2048 )
35+ .expireAfter (buildExpiryPolicy ())
36+ .build ();
37+ }
2938
3039 public Message handle (Message query , Function <Message , Response > delegate ) {
3140 return Objects .mapOrNull (this .handleRes (query , delegate ), Response ::getMessage );
3241 }
3342
3443 public Response handleRes (Message query , Function <Message , Response > delegate ) {
3544 final var key = buildKey (query );
36- final var res = this .cache .computeIfAbsentWithTTL (key , (k ) -> {
45+ final var cacheValue = this .cache .get (key , (k ) -> {
3746 log .trace ("status=lookup, key={}, req={}" , key , Messages .simplePrint (query ));
3847 final var _res = delegate .apply (query );
3948 if (_res == null ) {
@@ -42,12 +51,13 @@ public Response handleRes(Message query, Function<Message, Response> delegate) {
4251 }
4352 final var ttl = _res .getDpsTtl ();
4453 log .debug ("status=hotload, k={}, ttl={}, simpleMsg={}" , k , ttl , Messages .simplePrint (query ));
45- return Pair .of (_res , ttl );
54+ return CacheValue .of (_res , ttl );
4655 });
47- if (res == null ) {
56+ if (cacheValue == null ) {
4857 return null ;
4958 }
50- return res .withMessage (Messages .mergeId (query , res .getMessage ()));
59+ final var response = cacheValue .getResponse ();
60+ return response .withMessage (Messages .mergeId (query , response .getMessage ()));
5161 }
5262
5363 static String buildKey (Message reqMsg ) {
@@ -56,11 +66,11 @@ static String buildKey(Message reqMsg) {
5666 }
5767
5868 public int getSize () {
59- return this .cache .getSize ();
69+ return ( int ) this .cache .estimatedSize ();
6070 }
6171
6272 public void clear () {
63- this .cache .clear ();
73+ this .cache .invalidateAll ();
6474 }
6575
6676 public Map <String , CacheEntry > asMap () {
@@ -82,4 +92,51 @@ public Name name() {
8292 return this .name ;
8393 }
8494
95+ public CacheValue get (String key ) {
96+ return this .cache .getIfPresent (key );
97+ }
98+
99+ @ Value
100+ @ Builder
101+ static class CacheValue {
102+
103+ private Response response ;
104+ private Duration ttl ;
105+
106+ public static CacheValue of (Response res , Duration ttl ) {
107+ return CacheValue
108+ .builder ()
109+ .response (res )
110+ .ttl (ttl )
111+ .build ();
112+ }
113+
114+ public LocalDateTime getExpiresAt () {
115+ return this .response
116+ .getCreatedAt ()
117+ .plus (this .ttl )
118+ ;
119+ }
120+ }
121+
122+ private static Expiry <String , CacheValue > buildExpiryPolicy () {
123+ return new Expiry <>() {
124+ @ Override
125+ public long expireAfterCreate (String key , CacheValue value , long currentTime ) {
126+ return value .getTtl ().toNanos ();
127+ }
128+
129+ @ Override
130+ public long expireAfterUpdate (String key , CacheValue value , long currentTime , long currentDuration ) {
131+ return currentDuration ;
132+ }
133+
134+ @ Override
135+ public long expireAfterRead (String key , CacheValue value , long currentTime , long currentDuration ) {
136+ return currentDuration ;
137+ }
138+ };
139+ }
140+
141+
85142}
0 commit comments