@@ -87,26 +87,36 @@ S3ReadRequest.Acquired getOrCreateRequest(
8787 S3ReadRequest existingRequest = requests .get (key );
8888 while (true ) {
8989 if (existingRequest != null ) {
90+ // Try to acquire the existing request
9091 final S3ReadRequest .Acquired acquired = existingRequest .tryAcquire ();
9192 if (acquired != null ) {
9293 return acquired ;
93- } else {
94- remove (existingRequest );
9594 }
96- }
97- if (newAcquired == null ) {
98- newAcquired = S3ReadRequest .createAndAcquire (fragmentIndex , context );
99- }
100- if ((existingRequest = requests .putIfAbsent (key , newAcquired .request ())) == null ) {
101- if (log .isDebugEnabled ()) {
102- log .debug ().append ("Added new request to cache: " ).append (String .format ("ctx=%d " ,
103- System .identityHashCode (context ))).append (newAcquired .request ().requestStr ())
104- .endl ();
95+ // We could not acquire the existing request, so we need to replace it with a new one
96+ if (newAcquired == null ) {
97+ newAcquired = S3ReadRequest .createAndAcquire (fragmentIndex , context );
98+ }
99+ if (requests .replace (key , existingRequest , newAcquired .request ())) {
100+ // We successfully swapped out the old request for our new one
101+ return newAcquired ;
102+ }
103+ // Someone else modified the mapping in between, read the new mapping and loop again
104+ existingRequest = requests .get (key );
105+ } else {
106+ if (newAcquired == null ) {
107+ newAcquired = S3ReadRequest .createAndAcquire (fragmentIndex , context );
108+ }
109+ // Try to insert our new request if absent
110+ if ((existingRequest = requests .putIfAbsent (key , newAcquired .request ())) == null ) {
111+ if (log .isDebugEnabled ()) {
112+ log .debug ().append ("Added new request to cache: " ).append (String .format ("ctx=%d " ,
113+ System .identityHashCode (context ))).append (newAcquired .request ().requestStr ())
114+ .endl ();
115+ }
116+ return newAcquired ;
105117 }
106- return newAcquired ;
118+ // Another thread inserted a request first, loop again
107119 }
108- // TODO(deephaven-core#5486): Instead of remove + putIfAbsent pattern, we could have used replace + get
109- // pattern, but KeyedObjectHashMap potentially has a bug in replace method.
110120 }
111121 }
112122
0 commit comments