@@ -750,6 +750,12 @@ private void doPut(List<Put> puts) throws IOException {
750
750
751
751
// we need to periodically see if the writebuffer is full instead of waiting until the end of the List
752
752
n ++;
753
+ if (n % putWriteBufferCheck == 0 && currentWriteBufferSize > writeBufferSize ) {
754
+ flushCommits ();
755
+ }
756
+ }
757
+ if (autoFlush || currentWriteBufferSize > writeBufferSize ) {
758
+ flushCommits ();
753
759
}
754
760
}
755
761
@@ -1142,6 +1148,106 @@ public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, lo
1142
1148
return incrementColumnValue (row , family , qualifier , amount );
1143
1149
}
1144
1150
1151
+ public void flushCommits () throws IOException {
1152
+
1153
+ try {
1154
+ boolean [] resultSuccess = new boolean [writeBuffer .size ()];
1155
+ try {
1156
+ Map <String , Pair <List <Integer >, List <Cell >>> familyMap = new HashMap <String , Pair <List <Integer >, List <Cell >>>();
1157
+ for (int i = 0 ; i < writeBuffer .size (); i ++) {
1158
+ Put aPut = writeBuffer .get (i );
1159
+ Map <byte [], List <Cell >> innerFamilyMap = aPut .getFamilyCellMap ();
1160
+ if (innerFamilyMap .size () > 1 ) {
1161
+ // Bypass logic: directly construct BatchOperation for puts with family map size > 1
1162
+ try {
1163
+ BatchOperation batch = buildBatchOperation (this .tableNameString ,
1164
+ innerFamilyMap , false , null );
1165
+ BatchOperationResult results = batch .execute ();
1166
+
1167
+ boolean hasError = results .hasError ();
1168
+ resultSuccess [i ] = !hasError ;
1169
+ if (hasError ) {
1170
+ throw results .getFirstException ();
1171
+ }
1172
+ } catch (Exception e ) {
1173
+ logger .error (LCD .convert ("01-00008" ), tableNameString , null , autoFlush ,
1174
+ writeBuffer .size (), e );
1175
+ throw new IOException ("put table " + tableNameString + " error codes "
1176
+ + null + "auto flush " + autoFlush
1177
+ + " current buffer size " + writeBuffer .size (), e );
1178
+ }
1179
+ } else {
1180
+ // Existing logic for puts with family map size = 1
1181
+ for (Map .Entry <byte [], List <Cell >> entry : innerFamilyMap .entrySet ()) {
1182
+ String family = Bytes .toString (entry .getKey ());
1183
+ Pair <List <Integer >, List <Cell >> keyValueWithIndex = familyMap
1184
+ .get (family );
1185
+ if (keyValueWithIndex == null ) {
1186
+ keyValueWithIndex = new Pair <List <Integer >, List <Cell >>(
1187
+ new ArrayList <Integer >(), new ArrayList <Cell >());
1188
+ familyMap .put (family , keyValueWithIndex );
1189
+ }
1190
+ keyValueWithIndex .getFirst ().add (i );
1191
+ keyValueWithIndex .getSecond ().addAll (entry .getValue ());
1192
+ }
1193
+ }
1194
+ }
1195
+ for (Map .Entry <String , Pair <List <Integer >, List <Cell >>> entry : familyMap
1196
+ .entrySet ()) {
1197
+ List <Integer > errorCodeList = new ArrayList <Integer >(entry .getValue ()
1198
+ .getSecond ().size ());
1199
+ try {
1200
+ String targetTableName = getTargetTableName (this .tableNameString ,
1201
+ entry .getKey (), configuration );
1202
+
1203
+ BatchOperation batch = buildBatchOperation (targetTableName , entry
1204
+ .getValue ().getSecond (), false , null );
1205
+ BatchOperationResult results = batch .execute ();
1206
+
1207
+ errorCodeList = results .getErrorCodeList ();
1208
+ boolean hasError = results .hasError ();
1209
+ for (Integer index : entry .getValue ().getFirst ()) {
1210
+ resultSuccess [index ] = !hasError ;
1211
+ }
1212
+ if (hasError ) {
1213
+ throw results .getFirstException ();
1214
+ }
1215
+ } catch (Exception e ) {
1216
+ logger .error (LCD .convert ("01-00008" ), tableNameString , errorCodeList ,
1217
+ autoFlush , writeBuffer .size (), e );
1218
+ throw new IOException ("put table " + tableNameString + " error codes "
1219
+ + errorCodeList + "auto flush " + autoFlush
1220
+ + " current buffer size " + writeBuffer .size (), e );
1221
+ }
1222
+
1223
+ }
1224
+
1225
+ } finally {
1226
+ // mutate list so that it is empty for complete success, or contains
1227
+ // only failed records results are returned in the same order as the
1228
+ // requests in list walk the list backwards, so we can remove from list
1229
+ // without impacting the indexes of earlier members
1230
+ for (int i = resultSuccess .length - 1 ; i >= 0 ; i --) {
1231
+ if (resultSuccess [i ]) {
1232
+ // successful Puts are removed from the list here.
1233
+ writeBuffer .remove (i );
1234
+ }
1235
+ }
1236
+ }
1237
+ } finally {
1238
+ if (clearBufferOnFail ) {
1239
+ writeBuffer .clear ();
1240
+ currentWriteBufferSize = 0 ;
1241
+ } else {
1242
+ // the write buffer was adjusted by processBatchOfPuts
1243
+ currentWriteBufferSize = 0 ;
1244
+ for (Put aPut : writeBuffer ) {
1245
+ currentWriteBufferSize += aPut .heapSize ();
1246
+ }
1247
+ }
1248
+ }
1249
+ }
1250
+
1145
1251
@ Override
1146
1252
public void close () throws IOException {
1147
1253
if (cleanupPoolOnClose ) {
0 commit comments