|
20 | 20 | package org.apache.iotdb.db.queryengine.execution.fragment; |
21 | 21 |
|
22 | 22 | import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; |
| 23 | +import org.apache.iotdb.commons.exception.IllegalPathException; |
| 24 | +import org.apache.iotdb.commons.exception.MetadataException; |
| 25 | +import org.apache.iotdb.commons.path.MeasurementPath; |
| 26 | +import org.apache.iotdb.commons.path.PartialPath; |
23 | 27 | import org.apache.iotdb.db.conf.IoTDBDescriptor; |
| 28 | +import org.apache.iotdb.db.exception.query.QueryProcessException; |
24 | 29 | import org.apache.iotdb.db.queryengine.common.FragmentInstanceId; |
25 | 30 | import org.apache.iotdb.db.queryengine.common.PlanFragmentId; |
26 | 31 | import org.apache.iotdb.db.queryengine.exception.CpuNotEnoughException; |
|
30 | 35 | import org.apache.iotdb.db.queryengine.execution.exchange.sink.ISink; |
31 | 36 | import org.apache.iotdb.db.queryengine.execution.schedule.IDriverScheduler; |
32 | 37 | import org.apache.iotdb.db.storageengine.dataregion.DataRegion; |
| 38 | +import org.apache.iotdb.db.storageengine.dataregion.memtable.DeviceIDFactory; |
| 39 | +import org.apache.iotdb.db.storageengine.dataregion.memtable.IMemTable; |
| 40 | +import org.apache.iotdb.db.storageengine.dataregion.memtable.IWritableMemChunk; |
| 41 | +import org.apache.iotdb.db.storageengine.dataregion.memtable.IWritableMemChunkGroup; |
| 42 | +import org.apache.iotdb.db.storageengine.dataregion.memtable.PrimitiveMemTable; |
| 43 | +import org.apache.iotdb.db.storageengine.dataregion.memtable.ReadOnlyMemChunk; |
33 | 44 | import org.apache.iotdb.db.utils.datastructure.AlignedTVList; |
34 | 45 | import org.apache.iotdb.db.utils.datastructure.TVList; |
35 | 46 |
|
36 | 47 | import com.google.common.collect.ImmutableMap; |
37 | 48 | import org.apache.tsfile.enums.TSDataType; |
| 49 | +import org.apache.tsfile.file.metadata.enums.CompressionType; |
| 50 | +import org.apache.tsfile.file.metadata.enums.TSEncoding; |
| 51 | +import org.apache.tsfile.read.reader.IPointReader; |
| 52 | +import org.apache.tsfile.write.schema.MeasurementSchema; |
38 | 53 | import org.junit.Test; |
39 | 54 | import org.mockito.Mockito; |
40 | 55 |
|
41 | 56 | import java.io.ByteArrayOutputStream; |
| 57 | +import java.io.IOException; |
42 | 58 | import java.io.PrintStream; |
43 | 59 | import java.util.ArrayList; |
44 | 60 | import java.util.Collections; |
|
49 | 65 | import static org.apache.iotdb.db.queryengine.common.QueryId.MOCK_QUERY_ID; |
50 | 66 | import static org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceContext.createFragmentInstanceContext; |
51 | 67 | import static org.junit.Assert.assertEquals; |
| 68 | +import static org.junit.Assert.assertFalse; |
52 | 69 | import static org.junit.Assert.assertTrue; |
53 | 70 | import static org.junit.Assert.fail; |
54 | 71 |
|
@@ -157,6 +174,72 @@ public void testTVListOwnerTransfer() throws InterruptedException { |
157 | 174 | } |
158 | 175 | } |
159 | 176 |
|
| 177 | + @Test |
| 178 | + public void testTVListCloneForQuery() { |
| 179 | + IoTDBDescriptor.getInstance().getConfig().setDataNodeId(1); |
| 180 | + |
| 181 | + ExecutorService instanceNotificationExecutor = |
| 182 | + IoTDBThreadPoolFactory.newFixedThreadPool(1, "test-instance-notification"); |
| 183 | + |
| 184 | + try { |
| 185 | + String deviceId = "d1"; |
| 186 | + String measurementId = "s1"; |
| 187 | + IMemTable memTable = createMemTable(deviceId, measurementId); |
| 188 | + assertEquals(1, memTable.getMemTableMap().size()); |
| 189 | + IWritableMemChunkGroup memChunkGroup = memTable.getMemTableMap().values().iterator().next(); |
| 190 | + assertEquals(1, memChunkGroup.getMemChunkMap().size()); |
| 191 | + IWritableMemChunk memChunk = memChunkGroup.getMemChunkMap().values().iterator().next(); |
| 192 | + TVList tvList = memChunk.getWorkingTVList(); |
| 193 | + assertFalse(tvList.isSorted()); |
| 194 | + |
| 195 | + // FragmentInstance Context |
| 196 | + FragmentInstanceId id1 = new FragmentInstanceId(new PlanFragmentId(MOCK_QUERY_ID, 1), "1"); |
| 197 | + FragmentInstanceStateMachine stateMachine1 = |
| 198 | + new FragmentInstanceStateMachine(id1, instanceNotificationExecutor); |
| 199 | + FragmentInstanceContext fragmentInstanceContext1 = |
| 200 | + createFragmentInstanceContext(id1, stateMachine1); |
| 201 | + |
| 202 | + FragmentInstanceId id2 = new FragmentInstanceId(new PlanFragmentId(MOCK_QUERY_ID, 2), "2"); |
| 203 | + FragmentInstanceStateMachine stateMachine2 = |
| 204 | + new FragmentInstanceStateMachine(id2, instanceNotificationExecutor); |
| 205 | + FragmentInstanceContext fragmentInstanceContext2 = |
| 206 | + createFragmentInstanceContext(id2, stateMachine2); |
| 207 | + |
| 208 | + // query on memtable |
| 209 | + MeasurementPath fullPath = |
| 210 | + new MeasurementPath( |
| 211 | + deviceId, |
| 212 | + measurementId, |
| 213 | + new MeasurementSchema( |
| 214 | + measurementId, |
| 215 | + TSDataType.INT32, |
| 216 | + TSEncoding.RLE, |
| 217 | + CompressionType.UNCOMPRESSED, |
| 218 | + Collections.emptyMap())); |
| 219 | + ReadOnlyMemChunk readOnlyMemChunk1 = |
| 220 | + memTable.query(fragmentInstanceContext1, fullPath, Long.MIN_VALUE, null, null); |
| 221 | + ReadOnlyMemChunk readOnlyMemChunk2 = |
| 222 | + memTable.query(fragmentInstanceContext2, fullPath, Long.MIN_VALUE, null, null); |
| 223 | + |
| 224 | + IPointReader pointReader = readOnlyMemChunk1.getPointReader(); |
| 225 | + while (pointReader.hasNextTimeValuePair()) { |
| 226 | + pointReader.nextTimeValuePair(); |
| 227 | + } |
| 228 | + assertTrue(tvList.isSorted()); |
| 229 | + assertEquals( |
| 230 | + tvList.calculateRamSize(), |
| 231 | + fragmentInstanceContext1.getMemoryReservationContext().getReservedMemory()); |
| 232 | + } catch (QueryProcessException |
| 233 | + | IOException |
| 234 | + | MetadataException |
| 235 | + | MemoryNotEnoughException |
| 236 | + | IllegalArgumentException e) { |
| 237 | + fail(e.getMessage()); |
| 238 | + } finally { |
| 239 | + instanceNotificationExecutor.shutdown(); |
| 240 | + } |
| 241 | + } |
| 242 | + |
160 | 243 | private FragmentInstanceExecution createFragmentInstanceExecution(int id, Executor executor) |
161 | 244 | throws CpuNotEnoughException { |
162 | 245 | IDriverScheduler scheduler = Mockito.mock(IDriverScheduler.class); |
@@ -201,4 +284,20 @@ private TVList buildTVList() { |
201 | 284 | } |
202 | 285 | return tvList; |
203 | 286 | } |
| 287 | + |
| 288 | + private IMemTable createMemTable(String deviceId, String measurementId) |
| 289 | + throws IllegalPathException { |
| 290 | + IMemTable memTable = new PrimitiveMemTable("root.test", "1"); |
| 291 | + |
| 292 | + int rows = 100; |
| 293 | + for (int i = 0; i < 100; i++) { |
| 294 | + memTable.write( |
| 295 | + DeviceIDFactory.getInstance().getDeviceID(new PartialPath(deviceId)), |
| 296 | + Collections.singletonList( |
| 297 | + new MeasurementSchema(measurementId, TSDataType.INT32, TSEncoding.PLAIN)), |
| 298 | + rows - i - 1, |
| 299 | + new Object[] {i + 10}); |
| 300 | + } |
| 301 | + return memTable; |
| 302 | + } |
204 | 303 | } |
0 commit comments