11/*
2- * Copyright (c) 2000, 2020 , Oracle and/or its affiliates.
2+ * Copyright (c) 2000, 2023 , Oracle and/or its affiliates.
33 *
44 * Licensed under the Universal Permissive License v 1.0 as shown at
5- * http ://oss.oracle.com/licenses/upl.
5+ * https ://oss.oracle.com/licenses/upl.
66 */
77package com .tangosol .internal .util ;
88
99import com .oracle .coherence .common .util .Options ;
1010
11+ import com .tangosol .internal .util .processor .CacheProcessors ;
12+
1113import com .tangosol .net .AsyncNamedCache ;
1214import com .tangosol .net .CacheService ;
1315import com .tangosol .net .Member ;
1416import com .tangosol .net .NamedCache ;
1517import com .tangosol .net .PartitionedService ;
18+ import com .tangosol .net .partition .PartitionSet ;
1619
1720import com .tangosol .util .Filter ;
21+ import com .tangosol .util .ImmutableArrayList ;
1822import com .tangosol .util .InvocableMap ;
19-
20- import com .tangosol .internal .util .processor .CacheProcessors ;
2123import com .tangosol .util .InvocableMap .StreamingAggregator ;
22-
2324import com .tangosol .util .aggregator .AsynchronousAggregator ;
24-
25+ import com . tangosol . util . filter . PartitionedFilter ;
2526import com .tangosol .util .processor .AsynchronousProcessor ;
2627import com .tangosol .util .processor .SingleEntryAsynchronousProcessor ;
2728import com .tangosol .util .processor .StreamingAsynchronousProcessor ;
2829
30+ import java .util .ArrayList ;
2931import java .util .Collection ;
3032import java .util .HashMap ;
33+ import java .util .List ;
3134import java .util .Map ;
35+ import java .util .Set ;
3236
3337import java .util .concurrent .CompletableFuture ;
3438
@@ -76,6 +80,81 @@ public NamedCache<K, V> getNamedCache()
7680 return m_cache ;
7781 }
7882
83+ @ SuppressWarnings ("unchecked" )
84+ @ Override
85+ public CompletableFuture <Set <Map .Entry <K , V >>> entrySet (Filter <?> filter )
86+ {
87+ // optimized implementation that runs query against individual partitions
88+ // in parallel and aggregates the results
89+
90+ if (m_cache .getCacheService () instanceof PartitionedService && !(filter instanceof PartitionedFilter ))
91+ {
92+ int cParts = ((PartitionedService ) m_cache .getCacheService ()).getPartitionCount ();
93+ PartitionSet parts = new PartitionSet (cParts );
94+
95+ List <CompletableFuture <Void >> futures = new ArrayList <>(cParts );
96+ List <Map .Entry <K , V >> listEntries = new ArrayList <>();
97+
98+ for (int i = 0 ; i < cParts ; i ++)
99+ {
100+ parts .add (i );
101+ futures .add (invokeAll (new PartitionedFilter <>(filter , parts ), new AsynchronousProcessor <>(CacheProcessors .binaryGet (), i ))
102+ .thenAccept (results -> listEntries .addAll (results .entrySet ())));
103+ parts .remove (i );
104+ }
105+
106+ CompletableFuture <Set <Map .Entry <K , V >>> result = new CompletableFuture <>();
107+ CompletableFuture .allOf (futures .toArray (new CompletableFuture [futures .size ()]))
108+ .whenComplete ((v , err ) ->
109+ {
110+ if (err != null )
111+ {
112+ result .completeExceptionally (err );
113+ }
114+ else
115+ {
116+ result .complete (new ImmutableArrayList (listEntries ).getSet ());
117+ }
118+ });
119+
120+ return result ;
121+ }
122+ else
123+ {
124+ return AsyncNamedCache .super .entrySet (filter );
125+ }
126+ }
127+
128+ @ Override
129+ public CompletableFuture <Void > entrySet (Filter <?> filter , Consumer <? super Map .Entry <? extends K , ? extends V >> callback )
130+ {
131+ // optimized implementation that runs query against individual partitions
132+ // in parallel and aggregates the results
133+
134+ if (m_cache .getCacheService () instanceof PartitionedService && !(filter instanceof PartitionedFilter ))
135+ {
136+ int cParts = ((PartitionedService ) m_cache .getCacheService ()).getPartitionCount ();
137+ PartitionSet parts = new PartitionSet (cParts );
138+
139+ List <CompletableFuture <Void >> futures = new ArrayList <>(cParts );
140+
141+ for (int i = 0 ; i < cParts ; i ++)
142+ {
143+ parts .add (i );
144+ futures .add (invokeAll (new PartitionedFilter <>(filter , parts ),
145+ new StreamingAsynchronousProcessor <>(CacheProcessors .binaryGet (), i , callback ),
146+ callback )); // needed to ensure the streaming invokeAll is called!
147+ parts .remove (i );
148+ }
149+
150+ return CompletableFuture .allOf (futures .toArray (new CompletableFuture [futures .size ()]));
151+ }
152+ else
153+ {
154+ return AsyncNamedCache .super .entrySet (filter , callback );
155+ }
156+ }
157+
79158 @ Override
80159 public <R > CompletableFuture <R > invoke (K key ,
81160 InvocableMap .EntryProcessor <K , V , R > processor )
@@ -101,7 +180,7 @@ public <R> CompletableFuture<Map<K, R>> invokeAll(Collection<? extends K> collKe
101180 }
102181
103182 @ Override
104- public <R > CompletableFuture <Map <K , R >> invokeAll (Filter filter ,
183+ public <R > CompletableFuture <Map <K , R >> invokeAll (Filter <?> filter ,
105184 InvocableMap .EntryProcessor <K , V , R > processor )
106185 {
107186 AsynchronousProcessor <K , V , R > asyncProcessor =
@@ -126,7 +205,7 @@ public <R> CompletableFuture<Void> invokeAll(Collection<? extends K> collKeys,
126205 }
127206
128207 @ Override
129- public <R > CompletableFuture <Void > invokeAll (Filter filter ,
208+ public <R > CompletableFuture <Void > invokeAll (Filter <?> filter ,
130209 InvocableMap .EntryProcessor <K , V , R > processor ,
131210 Consumer <? super Map .Entry <? extends K , ? extends R >> callback )
132211 {
@@ -152,7 +231,7 @@ public <R> CompletableFuture<R> aggregate(
152231
153232 @ Override
154233 public <R > CompletableFuture <R > aggregate (
155- Filter filter , InvocableMap .EntryAggregator <? super K , ? super V , R > aggregator )
234+ Filter <?> filter , InvocableMap .EntryAggregator <? super K , ? super V , R > aggregator )
156235 {
157236 AsynchronousAggregator <? super K , ? super V , ?, R > asyncAggregator =
158237 instantiateAsyncAggregator (aggregator );
0 commit comments