|
28 | 28 | import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.RelationalInsertTabletNode; |
29 | 29 | import org.apache.iotdb.pipe.api.event.dml.insertion.TabletInsertionEvent; |
30 | 30 |
|
| 31 | +import org.apache.tsfile.enums.TSDataType; |
| 32 | +import org.apache.tsfile.utils.Binary; |
| 33 | +import org.apache.tsfile.utils.BitMap; |
31 | 34 | import org.apache.tsfile.utils.Pair; |
32 | 35 | import org.apache.tsfile.utils.PublicBAOS; |
33 | 36 | import org.apache.tsfile.utils.RamUsageEstimator; |
34 | 37 | import org.apache.tsfile.utils.ReadWriteIOUtils; |
| 38 | +import org.apache.tsfile.write.UnSupportedDataTypeException; |
35 | 39 | import org.apache.tsfile.write.record.Tablet; |
36 | 40 |
|
37 | 41 | import java.io.DataOutputStream; |
38 | 42 | import java.io.IOException; |
39 | 43 | import java.nio.ByteBuffer; |
| 44 | +import java.time.LocalDate; |
40 | 45 | import java.util.ArrayList; |
| 46 | +import java.util.Arrays; |
41 | 47 | import java.util.HashMap; |
42 | 48 | import java.util.List; |
43 | 49 | import java.util.Map; |
@@ -102,23 +108,28 @@ public PipeTransferTabletBatchReqV2 toTPipeTransferReq() throws IOException { |
102 | 108 | final String databaseName = insertTablets.getKey(); |
103 | 109 | for (final Map.Entry<String, Pair<Integer, List<Tablet>>> tabletEntry : |
104 | 110 | insertTablets.getValue().entrySet()) { |
105 | | - final List<Tablet> batchTablets = new ArrayList<>(); |
| 111 | + // needCopyFlag and tablet |
| 112 | + final List<Pair<Boolean, Tablet>> batchTablets = new ArrayList<>(); |
106 | 113 | for (final Tablet tablet : tabletEntry.getValue().getRight()) { |
107 | 114 | boolean success = false; |
108 | | - for (final Tablet batchTablet : batchTablets) { |
109 | | - if (batchTablet.append(tablet, tabletEntry.getValue().getLeft())) { |
| 115 | + for (final Pair<Boolean, Tablet> tabletPair : batchTablets) { |
| 116 | + if (tabletPair.getLeft()) { |
| 117 | + tabletPair.setRight(copyTablet(tabletPair.getRight())); |
| 118 | + tabletPair.setLeft(Boolean.FALSE); |
| 119 | + } |
| 120 | + if (tabletPair.getRight().append(tablet, tabletEntry.getValue().getLeft())) { |
110 | 121 | success = true; |
111 | 122 | break; |
112 | 123 | } |
113 | 124 | } |
114 | 125 | if (!success) { |
115 | | - batchTablets.add(tablet); |
| 126 | + batchTablets.add(new Pair<>(Boolean.TRUE, tablet)); |
116 | 127 | } |
117 | 128 | } |
118 | | - for (final Tablet batchTablet : batchTablets) { |
| 129 | + for (final Pair<Boolean, Tablet> tabletPair : batchTablets) { |
119 | 130 | try (final PublicBAOS byteArrayOutputStream = new PublicBAOS(); |
120 | 131 | final DataOutputStream outputStream = new DataOutputStream(byteArrayOutputStream)) { |
121 | | - batchTablet.serialize(outputStream); |
| 132 | + tabletPair.getRight().serialize(outputStream); |
122 | 133 | ReadWriteIOUtils.write(true, outputStream); |
123 | 134 | tabletBuffers.add( |
124 | 135 | ByteBuffer.wrap(byteArrayOutputStream.getBuf(), 0, byteArrayOutputStream.size())); |
@@ -214,4 +225,89 @@ private long constructTabletBatch(final Tablet tablet, final String databaseName |
214 | 225 | currentBatch.getRight().add(tablet); |
215 | 226 | return PipeMemoryWeightUtil.calculateTabletSizeInBytes(tablet) + 4; |
216 | 227 | } |
| 228 | + |
| 229 | + public static Tablet copyTablet(final Tablet tablet) { |
| 230 | + final Object[] copiedValues = new Object[tablet.getValues().length]; |
| 231 | + for (int i = 0; i < tablet.getValues().length; i++) { |
| 232 | + if (tablet.getValues()[i] == null |
| 233 | + || tablet.getSchemas() == null |
| 234 | + || tablet.getSchemas().get(i) == null) { |
| 235 | + continue; |
| 236 | + } |
| 237 | + copiedValues[i] = |
| 238 | + copyValueList( |
| 239 | + tablet.getValues()[i], tablet.getSchemas().get(i).getType(), tablet.getRowSize()); |
| 240 | + } |
| 241 | + |
| 242 | + BitMap[] bitMaps = null; |
| 243 | + if (tablet.getBitMaps() != null) { |
| 244 | + bitMaps = |
| 245 | + Arrays.stream(tablet.getBitMaps()) |
| 246 | + .map( |
| 247 | + bitMap -> { |
| 248 | + if (bitMap != null) { |
| 249 | + final byte[] data = bitMap.getByteArray(); |
| 250 | + return new BitMap(bitMap.getSize(), Arrays.copyOf(data, data.length)); |
| 251 | + } |
| 252 | + return null; |
| 253 | + }) |
| 254 | + .toArray(BitMap[]::new); |
| 255 | + } |
| 256 | + |
| 257 | + return new Tablet( |
| 258 | + tablet.getTableName(), |
| 259 | + new ArrayList<>(tablet.getSchemas()), |
| 260 | + new ArrayList<>(tablet.getColumnTypes()), |
| 261 | + Arrays.copyOf(tablet.getTimestamps(), tablet.getRowSize()), |
| 262 | + copiedValues, |
| 263 | + bitMaps, |
| 264 | + tablet.getRowSize()); |
| 265 | + } |
| 266 | + |
| 267 | + private static Object copyValueList( |
| 268 | + final Object valueList, final TSDataType dataType, final int rowSize) { |
| 269 | + switch (dataType) { |
| 270 | + case BOOLEAN: |
| 271 | + final boolean[] boolValues = (boolean[]) valueList; |
| 272 | + final boolean[] copiedBoolValues = new boolean[rowSize]; |
| 273 | + System.arraycopy(boolValues, 0, copiedBoolValues, 0, rowSize); |
| 274 | + return copiedBoolValues; |
| 275 | + case INT32: |
| 276 | + final int[] intValues = (int[]) valueList; |
| 277 | + final int[] copiedIntValues = new int[rowSize]; |
| 278 | + System.arraycopy(intValues, 0, copiedIntValues, 0, rowSize); |
| 279 | + return copiedIntValues; |
| 280 | + case DATE: |
| 281 | + final LocalDate[] dateValues = (LocalDate[]) valueList; |
| 282 | + final LocalDate[] copiedDateValues = new LocalDate[rowSize]; |
| 283 | + System.arraycopy(dateValues, 0, copiedDateValues, 0, rowSize); |
| 284 | + return copiedDateValues; |
| 285 | + case INT64: |
| 286 | + case TIMESTAMP: |
| 287 | + final long[] longValues = (long[]) valueList; |
| 288 | + final long[] copiedLongValues = new long[rowSize]; |
| 289 | + System.arraycopy(longValues, 0, copiedLongValues, 0, rowSize); |
| 290 | + return copiedLongValues; |
| 291 | + case FLOAT: |
| 292 | + final float[] floatValues = (float[]) valueList; |
| 293 | + final float[] copiedFloatValues = new float[rowSize]; |
| 294 | + System.arraycopy(floatValues, 0, copiedFloatValues, 0, rowSize); |
| 295 | + return copiedFloatValues; |
| 296 | + case DOUBLE: |
| 297 | + final double[] doubleValues = (double[]) valueList; |
| 298 | + final double[] copiedDoubleValues = new double[rowSize]; |
| 299 | + System.arraycopy(doubleValues, 0, copiedDoubleValues, 0, rowSize); |
| 300 | + return copiedDoubleValues; |
| 301 | + case TEXT: |
| 302 | + case BLOB: |
| 303 | + case STRING: |
| 304 | + final Binary[] binaryValues = (Binary[]) valueList; |
| 305 | + final Binary[] copiedBinaryValues = new Binary[rowSize]; |
| 306 | + System.arraycopy(binaryValues, 0, copiedBinaryValues, 0, rowSize); |
| 307 | + return copiedBinaryValues; |
| 308 | + default: |
| 309 | + throw new UnSupportedDataTypeException( |
| 310 | + String.format("Data type %s is not supported.", dataType)); |
| 311 | + } |
| 312 | + } |
217 | 313 | } |
0 commit comments