3838import java .util .concurrent .TimeUnit ;
3939import java .util .concurrent .atomic .AtomicBoolean ;
4040import java .util .concurrent .atomic .AtomicInteger ;
41+ import java .util .function .BiFunction ;
4142import java .util .jar .JarFile ;
4243import java .util .jar .Manifest ;
4344
@@ -1783,7 +1784,7 @@ public <T> CollectionFuture<Map<Integer, CollectionOperationStatus>> asyncBopPip
17831784 insertList .add (new BTreePipedInsert <>(key , elementMap , attributesForCreate , tc ));
17841785 }
17851786 }
1786- return asyncCollectionPipedInsert (key , insertList );
1787+ return syncCollectionPipedInsert (key , insertList );
17871788 }
17881789
17891790 @ Override
@@ -1806,7 +1807,7 @@ public <T> CollectionFuture<Map<Integer, CollectionOperationStatus>> asyncBopPip
18061807 insertList .add (new ByteArraysBTreePipedInsert <>(key , elementList , attributesForCreate , tc ));
18071808 }
18081809 }
1809- return asyncCollectionPipedInsert (key , insertList );
1810+ return syncCollectionPipedInsert (key , insertList );
18101811 }
18111812
18121813 @ Override
@@ -1833,7 +1834,7 @@ public <T> CollectionFuture<Map<Integer, CollectionOperationStatus>> asyncMopPip
18331834 insertList .add (new MapPipedInsert <>(key , elementMap , attributesForCreate , tc ));
18341835 }
18351836 }
1836- return asyncCollectionPipedInsert (key , insertList );
1837+ return syncCollectionPipedInsert (key , insertList );
18371838 }
18381839
18391840 @ Override
@@ -1859,7 +1860,7 @@ public <T> CollectionFuture<Map<Integer, CollectionOperationStatus>> asyncLopPip
18591860 }
18601861 }
18611862 }
1862- return asyncCollectionPipedInsert (key , insertList );
1863+ return syncCollectionPipedInsert (key , insertList );
18631864 }
18641865
18651866 @ Override
@@ -1882,7 +1883,7 @@ public <T> CollectionFuture<Map<Integer, CollectionOperationStatus>> asyncSopPip
18821883 insertList .add (new SetPipedInsert <>(key , elementList , attributesForCreate , tc ));
18831884 }
18841885 }
1885- return asyncCollectionPipedInsert (key , insertList );
1886+ return syncCollectionPipedInsert (key , insertList );
18861887 }
18871888
18881889 @ Override
@@ -3106,6 +3107,90 @@ public void gotStatus(Integer index, OperationStatus status) {
31063107 return rv ;
31073108 }
31083109
3110+ /**
3111+ * insert items into collection synchronously.
3112+ *
3113+ * @param key arcus cache key
3114+ * @param insertList must not be empty.
3115+ * @return future holding the map of element index and the reason why insert operation failed
3116+ */
3117+ private <T > CollectionFuture <Map <Integer , CollectionOperationStatus >> syncCollectionPipedInsert (
3118+ final String key , final List <CollectionPipedInsert <T >> insertList ) {
3119+ final CountDownLatch latch = new CountDownLatch (1 );
3120+ final PipedCollectionFuture <Integer , CollectionOperationStatus > rv =
3121+ new PipedCollectionFuture <>(latch , operationTimeout );
3122+
3123+ final List <Operation > ops = new ArrayList <>(insertList .size ());
3124+ BiFunction <Integer , Integer , OperationCallback > makeCallback = (opIdx , itemCount ) -> new PipedOperationCallback () {
3125+
3126+ private int lastExecutedIndex ;
3127+
3128+ public void receivedStatus (OperationStatus status ) {
3129+ CollectionOperationStatus cstatus ;
3130+
3131+ if (status instanceof CollectionOperationStatus ) {
3132+ cstatus = (CollectionOperationStatus ) status ;
3133+ } else {
3134+ getLogger ().warn ("Unhandled state: " + status );
3135+ cstatus = new CollectionOperationStatus (status );
3136+ }
3137+ rv .setOperationStatus (cstatus );
3138+ }
3139+
3140+ public void complete () {
3141+ if (rv .getOperationStatus ().isSuccess ()) {
3142+ if (opIdx + 1 < ops .size ()) {
3143+ // If operations are succeed and next operation exists, then add it.
3144+ Operation nextOp = ops .get (opIdx + 1 );
3145+ rv .addOperation (nextOp );
3146+ addOp (key , nextOp );
3147+ } else {
3148+ latch .countDown ();
3149+ }
3150+ } else {
3151+ // If this operation has been errored or cancelled,
3152+ // add the command not executed in a operation as not executed state.
3153+ // The remaining operations will be also not executed state but not added into failed result.
3154+ int nextIndex = 0 ;
3155+ if (lastExecutedIndex < itemCount - 1 ) {
3156+ // command remained in the same operation object.
3157+ nextIndex = lastExecutedIndex + 1 + (opIdx * MAX_PIPED_ITEM_COUNT );
3158+ } else if (opIdx + 1 < ops .size ()) {
3159+ // command remained in the next operation object.
3160+ nextIndex = (opIdx + 1 ) * MAX_PIPED_ITEM_COUNT ;
3161+ }
3162+ if (nextIndex > 0 ) {
3163+ rv .addEachResult (nextIndex ,
3164+ new CollectionOperationStatus (false , "NOT_EXECUTED" , CollectionResponse .NOT_EXECUTED ));
3165+ }
3166+ latch .countDown ();
3167+ }
3168+ }
3169+
3170+ public void gotStatus (Integer index , OperationStatus status ) {
3171+ if (!status .isSuccess ()) {
3172+ if (status instanceof CollectionOperationStatus ) {
3173+ rv .addEachResult (index + (opIdx * MAX_PIPED_ITEM_COUNT ),
3174+ (CollectionOperationStatus ) status );
3175+ } else {
3176+ rv .addEachResult (index + (opIdx * MAX_PIPED_ITEM_COUNT ),
3177+ new CollectionOperationStatus (status ));
3178+ }
3179+ }
3180+ this .lastExecutedIndex = index ;
3181+ }
3182+ };
3183+
3184+ for (int i = 0 ; i < insertList .size (); i ++) {
3185+ final CollectionPipedInsert <T > insert = insertList .get (i );
3186+ Operation op = opFact .collectionPipedInsert (key , insert , makeCallback .apply (i , insert .getItemCount ()));
3187+ ops .add (op );
3188+ }
3189+ rv .addOperation (ops .get (0 ));
3190+ addOp (key , ops .get (0 ));
3191+ return rv ;
3192+ }
3193+
31093194 @ Override
31103195 public Future <Map <String , CollectionOperationStatus >> asyncBopInsertBulk (
31113196 List <String > keyList , long bkey , byte [] eFlag , Object value ,
0 commit comments