This is an automated email from the ASF dual-hosted git repository.
qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 102bd16 [IOTDB-829] Accelerate delete timeseries (#1732)
102bd16 is described below
commit 102bd1656c39e05e91ae492c31f6ca5389e19965
Author: wshao08 <[email protected]>
AuthorDate: Mon Oct 19 12:02:29 2020 +0800
[IOTDB-829] Accelerate delete timeseries (#1732)
---
.../org/apache/iotdb/db/engine/StorageEngine.java | 28 +++---
.../iotdb/db/engine/memtable/AbstractMemTable.java | 33 ++++---
.../apache/iotdb/db/engine/memtable/IMemTable.java | 9 +-
.../db/engine/merge/manage/MergeResource.java | 10 +-
.../engine/storagegroup/StorageGroupProcessor.java | 101 +++++++++++----------
.../db/engine/storagegroup/TsFileProcessor.java | 19 ++--
.../org/apache/iotdb/db/metadata/MManager.java | 5 +
.../java/org/apache/iotdb/db/metadata/MTree.java | 42 +++++++--
.../org/apache/iotdb/db/metadata/PartialPath.java | 53 ++++++++++-
.../org/apache/iotdb/db/monitor/StatMonitor.java | 2 +-
.../apache/iotdb/db/qp/executor/PlanExecutor.java | 25 +----
.../iotdb/db/query/context/QueryContext.java | 7 +-
.../chunk/metadata/DiskChunkMetadataLoader.java | 7 +-
.../org/apache/iotdb/db/utils/FileLoaderUtils.java | 2 +-
.../iotdb/db/writelog/recover/LogReplayer.java | 11 ++-
.../engine/modification/DeletionFileNodeTest.java | 28 +++---
.../db/engine/modification/DeletionQueryTest.java | 52 +++++------
.../storagegroup/StorageGroupProcessorTest.java | 5 +-
.../engine/storagegroup/TsFileProcessorTest.java | 9 +-
.../org/apache/iotdb/db/metadata/MTreeTest.java | 21 +++++
.../apache/iotdb/db/metadata/PartialPathTest.java | 27 +++++-
21 files changed, 320 insertions(+), 176 deletions(-)
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
index 88cd7c7..0823608 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
@@ -447,15 +447,16 @@ public class StorageEngine implements IService {
// TODO
}
- /**
- * delete data of timeseries "{deviceId}.{measurementId}" with time <=
timestamp.
- */
- public void delete(PartialPath deviceId, String measurementId, long
startTime, long endTime)
- throws StorageEngineException {
- StorageGroupProcessor storageGroupProcessor = getProcessor(deviceId);
+ public void delete(PartialPath path, long startTime, long endTime)
+ throws StorageEngineException {
try {
- storageGroupProcessor.delete(deviceId, measurementId, startTime,
endTime);
- } catch (IOException e) {
+ List<PartialPath> sgPaths =
IoTDB.metaManager.searchAllRelatedStorageGroups(path);
+ for (PartialPath storageGroupPath : sgPaths) {
+ StorageGroupProcessor storageGroupProcessor =
getProcessor(storageGroupPath);
+ PartialPath newPath = path.alterPrefixPath(storageGroupPath);
+ storageGroupProcessor.delete(newPath, startTime, endTime);
+ }
+ } catch (IOException | MetadataException e) {
throw new StorageEngineException(e.getMessage());
}
}
@@ -463,12 +464,15 @@ public class StorageEngine implements IService {
/**
* delete data of timeseries "{deviceId}.{measurementId}"
*/
- public void deleteTimeseries(PartialPath deviceId, String measurementId)
+ public void deleteTimeseries(PartialPath path)
throws StorageEngineException {
- StorageGroupProcessor storageGroupProcessor = getProcessor(deviceId);
try {
- storageGroupProcessor.delete(deviceId, measurementId, Long.MIN_VALUE,
Long.MAX_VALUE);
- } catch (IOException e) {
+ for (PartialPath storageGroupPath :
IoTDB.metaManager.searchAllRelatedStorageGroups(path)) {
+ StorageGroupProcessor storageGroupProcessor =
getProcessor(storageGroupPath);
+ PartialPath newPath = path.alterPrefixPath(storageGroupPath);
+ storageGroupProcessor.delete(newPath, Long.MIN_VALUE, Long.MAX_VALUE);
+ }
+ } catch (IOException | MetadataException e) {
throw new StorageEngineException(e.getMessage());
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index e52dd1c..2a17107 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -21,15 +21,18 @@ package org.apache.iotdb.db.engine.memtable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.engine.modification.Deletion;
import org.apache.iotdb.db.engine.modification.Modification;
import org.apache.iotdb.db.engine.querycontext.ReadOnlyMemChunk;
import org.apache.iotdb.db.exception.WriteProcessException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
import org.apache.iotdb.db.rescon.TVListAllocator;
@@ -230,20 +233,24 @@ public abstract class AbstractMemTable implements
IMemTable {
}
@Override
- public void delete(String deviceId, String measurementId, long
startTimestamp, long endTimestamp) {
- Map<String, IWritableMemChunk> deviceMap = memTableMap.get(deviceId);
- if (deviceMap != null) {
- IWritableMemChunk chunk = deviceMap.get(measurementId);
- if (chunk == null) {
- return;
- }
- // If startTimestamp == Long.MIN_VALUE && endTimestamp == Long.MAX_VALUE,
- // it means that the whole timeseries is deleted
- if (startTimestamp == Long.MIN_VALUE && endTimestamp == Long.MAX_VALUE) {
- deviceMap.remove(measurementId);
+ public void delete(PartialPath originalPath, PartialPath devicePath, long
startTimestamp, long endTimestamp) {
+ Map<String, IWritableMemChunk> deviceMap =
memTableMap.get(devicePath.getFullPath());
+ if (deviceMap == null) {
+ return;
+ }
+
+ Iterator<Entry<String, IWritableMemChunk>> iter =
deviceMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Entry<String, IWritableMemChunk> entry = iter.next();
+ IWritableMemChunk chunk = entry.getValue();
+ PartialPath fullPath = devicePath.concatNode(entry.getKey());
+ if (originalPath.matchFullPath(fullPath)) {
+ if (startTimestamp == Long.MIN_VALUE && endTimestamp ==
Long.MAX_VALUE) {
+ iter.remove();
+ }
+ int deletedPointsNumber = chunk.delete(startTimestamp, endTimestamp);
+ totalPointsNum -= deletedPointsNumber;
}
- int deletedPointsNumber = chunk.delete(startTimestamp, endTimestamp);
- totalPointsNum -= deletedPointsNumber;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
index c291471..3cadfd9 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/IMemTable.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.db.engine.modification.Deletion;
import org.apache.iotdb.db.engine.querycontext.ReadOnlyMemChunk;
import org.apache.iotdb.db.exception.WriteProcessException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -87,14 +88,14 @@ public interface IMemTable {
/**
* Delete data in it whose timestamp <= 'timestamp' and belonging to
timeseries
- * deviceId.measurementId. Only called for non-flushing MemTable.
+ * path. Only called for non-flushing MemTable.
*
- * @param deviceId the deviceId of the timeseries to be deleted.
- * @param measurementId the measurementId of the timeseries to be deleted.
+ * @param path the PartialPath the timeseries to be deleted.
+ * @param devicePath the device path of the timeseries to be deleted.
* @param startTimestamp the lower-bound of deletion time.
* @param endTimestamp the upper-bound of deletion time
*/
- void delete(String deviceId, String measurementId, long startTimestamp, long
endTimestamp);
+ void delete(PartialPath path, PartialPath devicePath, long startTimestamp,
long endTimestamp);
/**
* Delete data in it whose timestamp <= 'timestamp' and belonging to
timeseries
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/merge/manage/MergeResource.java
b/server/src/main/java/org/apache/iotdb/db/engine/merge/manage/MergeResource.java
index 8b27ba8..46f93b0 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/merge/manage/MergeResource.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/merge/manage/MergeResource.java
@@ -25,11 +25,13 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import org.apache.iotdb.db.engine.modification.Modification;
@@ -170,9 +172,7 @@ public class MergeResource {
}
/**
- * Get the modifications of a timeseries in the ModificationFile of a
TsFile. Once the
- * modifications of the timeseries are found out, they will be removed from
the list to boost
- * the next query, so two calls of the same file and timeseries are
forbidden.
+ * Get the modifications of a timeseries in the ModificationFile of a TsFile.
* @param path name of the time series
*/
public List<Modification> getModifications(TsFileResource tsFileResource,
PartialPath path) {
@@ -181,12 +181,10 @@ public class MergeResource {
resource -> new
LinkedList<>(resource.getModFile().getModifications()));
List<Modification> pathModifications = new ArrayList<>();
Iterator<Modification> modificationIterator = modifications.iterator();
- // each path is visited only once in a merge, so the modifications can be
removed after visiting
while (modificationIterator.hasNext()) {
Modification modification = modificationIterator.next();
- if (modification.getPath().equals(path)) {
+ if (modification.getPath().matchFullPath(path)) {
pathModifications.add(modification);
- modificationIterator.remove();
}
}
return pathModifications;
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
index 28783ac..9e8f4ef 100755
---
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
@@ -1360,18 +1360,15 @@ public class StorageGroupProcessor {
return true;
}
-
/**
* Delete data whose timestamp <= 'timestamp' and belongs to the time series
* deviceId.measurementId.
*
- * @param deviceId the deviceId of the timeseries to be deleted.
- * @param measurementId the measurementId of the timeseries to be deleted.
- * @param startTime the startTime of delete range.
- * @param endTime the endTime of delete range.
+ * @param path the timeseries path of the to be deleted.
+ * @param startTime the startTime of delete range.
+ * @param endTime the endTime of delete range.
*/
- public void delete(PartialPath deviceId, String measurementId, long
startTime, long endTime)
- throws IOException {
+ public void delete(PartialPath path, long startTime, long endTime) throws
IOException {
// TODO: how to avoid partial deletion?
// FIXME: notice that if we may remove a SGProcessor out of memory, we
need to close all opened
//mod files in mergingModification, sequenceFileList, and
unsequenceFileList
@@ -1383,33 +1380,35 @@ public class StorageGroupProcessor {
List<ModificationFile> updatedModFiles = new ArrayList<>();
try {
- Long lastUpdateTime = null;
- for (Map<String, Long> latestTimeMap : latestTimeForEachDevice.values())
{
- Long curTime = latestTimeMap.get(deviceId.getFullPath());
- if (curTime != null && (lastUpdateTime == null || lastUpdateTime <
curTime)) {
- lastUpdateTime = curTime;
+ Set<PartialPath> devicePaths =
IoTDB.metaManager.getDevices(path.getDevicePath());
+ for (PartialPath device : devicePaths) {
+ Long lastUpdateTime = null;
+ for (Map<String, Long> latestTimeMap :
latestTimeForEachDevice.values()) {
+ Long curTime = latestTimeMap.get(device.getFullPath());
+ if (curTime != null && (lastUpdateTime == null || lastUpdateTime <
curTime)) {
+ lastUpdateTime = curTime;
+ }
}
- }
-
- // There is no tsfile data, the delete operation is invalid
- if (lastUpdateTime == null) {
- logger.debug("No device {} in SG {}, deletion invalid", deviceId,
storageGroupName);
- return;
+ // There is no tsfile data, the delete operation is invalid
+ if (lastUpdateTime == null) {
+ logger.debug("No device {} in SG {}, deletion invalid", device,
storageGroupName);
+ return;
+ }
+ // delete Last cache record if necessary
+ tryToDeleteLastCache(device, path, startTime, endTime);
}
// write log to impacted working TsFileProcessors
- logDeletion(startTime, endTime, deviceId, measurementId);
- // delete Last cache record if necessary
- tryToDeleteLastCache(deviceId, measurementId, startTime, endTime);
- Deletion deletion = new Deletion(deviceId.concatNode(measurementId),
- MERGE_MOD_START_VERSION_NUM, startTime, endTime);
+ logDeletion(startTime, endTime, path);
+
+ Deletion deletion = new Deletion(path, MERGE_MOD_START_VERSION_NUM,
startTime, endTime);
if (mergingModification != null) {
mergingModification.write(deletion);
updatedModFiles.add(mergingModification);
}
- deleteDataInFiles(tsFileManagement.getTsFileList(true), deletion,
updatedModFiles);
- deleteDataInFiles(tsFileManagement.getTsFileList(false), deletion,
updatedModFiles);
+ deleteDataInFiles(tsFileManagement.getTsFileList(true), deletion,
devicePaths, updatedModFiles);
+ deleteDataInFiles(tsFileManagement.getTsFileList(false), deletion,
devicePaths, updatedModFiles);
} catch (Exception e) {
// roll back
@@ -1424,13 +1423,12 @@ public class StorageGroupProcessor {
}
}
- private void logDeletion(long startTime, long endTime, PartialPath deviceId,
String measurementId)
+ private void logDeletion(long startTime, long endTime, PartialPath path)
throws IOException {
long timePartitionStartId = StorageEngine.getTimePartition(startTime);
long timePartitionEndId = StorageEngine.getTimePartition(endTime);
if (IoTDBDescriptor.getInstance().getConfig().isEnableWal()) {
- DeletePlan deletionPlan = new DeletePlan(startTime, endTime,
- deviceId.concatNode(measurementId));
+ DeletePlan deletionPlan = new DeletePlan(startTime, endTime, path);
for (Map.Entry<Long, TsFileProcessor> entry :
workSequenceTsFileProcessors.entrySet()) {
if (timePartitionStartId <= entry.getKey() && entry.getKey() <=
timePartitionEndId) {
entry.getValue().getLogNode().write(deletionPlan);
@@ -1445,15 +1443,23 @@ public class StorageGroupProcessor {
}
}
+ private boolean canSkipDelete(TsFileResource tsFileResource,
Set<PartialPath> devicePaths,
+ long deleteStart, long deleteEnd) {
+ for (PartialPath device : devicePaths) {
+ if (tsFileResource.containsDevice(device.getFullPath()) &&
+ (deleteEnd >= tsFileResource.getStartTime(device.getFullPath())
&&
+ deleteStart <=
tsFileResource.getOrDefaultEndTime(device.getFullPath(), Long.MAX_VALUE))) {
+ return false;
+ }
+ }
+ return true;
+ }
private void deleteDataInFiles(Collection<TsFileResource>
tsFileResourceList, Deletion deletion,
- List<ModificationFile> updatedModFiles)
- throws IOException {
- String deviceId = deletion.getDevice();
+ Set<PartialPath> devicePaths, List<ModificationFile> updatedModFiles)
+ throws IOException, MetadataException {
for (TsFileResource tsFileResource : tsFileResourceList) {
- if (!tsFileResource.containsDevice(deviceId) ||
- deletion.getEndTime() < tsFileResource.getStartTime(deviceId) ||
- deletion.getStartTime() >
tsFileResource.getOrDefaultEndTime(deviceId, Long.MAX_VALUE)) {
+ if (canSkipDelete(tsFileResource, devicePaths, deletion.getStartTime(),
deletion.getEndTime())) {
continue;
}
@@ -1468,7 +1474,7 @@ public class StorageGroupProcessor {
// delete data in memory of unsealed file
if (!tsFileResource.isClosed()) {
TsFileProcessor tsfileProcessor =
tsFileResource.getUnsealedFileProcessor();
- tsfileProcessor.deleteDataInMemory(deletion);
+ tsfileProcessor.deleteDataInMemory(deletion, devicePaths);
}
// add a record in case of rollback
@@ -1476,18 +1482,21 @@ public class StorageGroupProcessor {
}
}
- private void tryToDeleteLastCache(PartialPath deviceId, String
measurementId, long startTime,
- long endTime) throws WriteProcessException {
+ private void tryToDeleteLastCache(PartialPath deviceId, PartialPath
originalPath,
+ long startTime, long endTime) throws WriteProcessException {
+ if (!IoTDBDescriptor.getInstance().getConfig().isLastCacheEnabled()) {
+ return;
+ }
try {
- MManager manager = MManager.getInstance();
- MNode node = manager.getDeviceNodeWithAutoCreate(deviceId);
-
- MNode measurementNode = node.getChild(measurementId);
- if (measurementNode != null) {
- TimeValuePair lastPair = ((MeasurementMNode)
measurementNode).getCachedLast();
- if (lastPair != null && startTime <= lastPair.getTimestamp()
- && lastPair.getTimestamp() <= endTime) {
- ((MeasurementMNode) measurementNode).resetCache();
+ MNode node = IoTDB.metaManager.getDeviceNode(deviceId);
+
+ for (MNode measurementNode : node.getChildren().values()) {
+ if (measurementNode != null &&
originalPath.matchFullPath(measurementNode.getPartialPath())) {
+ TimeValuePair lastPair = ((MeasurementMNode)
measurementNode).getCachedLast();
+ if (lastPair != null && startTime <= lastPair.getTimestamp()
+ && lastPair.getTimestamp() <= endTime) {
+ ((MeasurementMNode) measurementNode).resetCache();
+ }
}
}
} catch (MetadataException e) {
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index bd48984..536e7cc 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -48,7 +49,11 @@ import
org.apache.iotdb.db.engine.storagegroup.StorageGroupProcessor.UpdateEndTi
import org.apache.iotdb.db.engine.version.VersionController;
import org.apache.iotdb.db.exception.TsFileProcessorException;
import org.apache.iotdb.db.exception.WriteProcessException;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.MManager;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.MNode;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
import org.apache.iotdb.db.query.context.QueryContext;
@@ -226,7 +231,8 @@ public class TsFileProcessor {
* <p>
* Delete data in both working MemTable and flushing MemTables.
*/
- public void deleteDataInMemory(Deletion deletion) {
+ public void deleteDataInMemory(Deletion deletion, Set<PartialPath>
devicePaths)
+ throws MetadataException {
flushQueryLock.writeLock().lock();
if (logger.isDebugEnabled()) {
logger
@@ -234,9 +240,10 @@ public class TsFileProcessor {
}
try {
if (workMemTable != null) {
- workMemTable
- .delete(deletion.getDevice(), deletion.getMeasurement(),
deletion.getStartTime(),
- deletion.getEndTime());
+ for (PartialPath device : devicePaths) {
+ workMemTable.delete(deletion.getPath(), device,
deletion.getStartTime(),
+ deletion.getEndTime());
+ }
}
// flushing memTables are immutable, only record this deletion in these
memTables for query
for (IMemTable memTable : flushingMemTables) {
@@ -720,7 +727,7 @@ public class TsFileProcessor {
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity
warning
public void query(String deviceId, String measurementId, TSDataType
dataType, TSEncoding encoding,
Map<String, String> props, QueryContext context,
- List<TsFileResource> tsfileResourcesForQuery) throws IOException {
+ List<TsFileResource> tsfileResourcesForQuery) throws IOException,
MetadataException {
if (logger.isDebugEnabled()) {
logger.debug("{}: {} get flushQueryLock and vmMergeLock read lock",
storageGroupName,
tsFileResource.getTsFile().getName());
@@ -748,7 +755,7 @@ public class TsFileProcessor {
ModificationFile modificationFile = tsFileResource.getModFile();
List<Modification> modifications =
context.getPathModifications(modificationFile,
- deviceId + IoTDBConstant.PATH_SEPARATOR + measurementId);
+ new PartialPath(deviceId + IoTDBConstant.PATH_SEPARATOR +
measurementId));
List<ChunkMetadata> chunkMetadataList = writer
.getVisibleMetadataList(deviceId, measurementId, dataType);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index 73ce5db..efeb4af 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -700,6 +700,11 @@ public class MManager {
return mtree.getAllStorageGroupPaths();
}
+ public List<PartialPath> searchAllRelatedStorageGroups(PartialPath path)
+ throws MetadataException {
+ return mtree.searchAllRelatedStorageGroups(path);
+ }
+
/**
* Get all storage group under given prefixPath.
*
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index 0fe0a5e..09dffb0 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -630,7 +630,27 @@ public class MTree implements Serializable {
}
/**
- * Get all storage group under give path
+ * Get the storage group that given path belonged to or under given path
+ * All related storage groups refer two cases:
+ * 1. Storage groups with a prefix that is identical to path, e.g. given
path "root.sg1",
+ * storage group "root.sg1.sg2" and "root.sg1.sg3" will be added into
result list.
+ * 2. Storage group that this path belongs to, e.g. given path
"root.sg1.d1", and it is in
+ * storage group "root.sg1". Then we adds "root.sg1" into result list.
+ *
+ * @return a list contains all storage groups related to given path
+ */
+ List<PartialPath> searchAllRelatedStorageGroups(PartialPath path) throws
MetadataException {
+ String[] nodes = path.getNodes();
+ if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
+ throw new IllegalPathException(path.getFullPath());
+ }
+ List<PartialPath> storageGroupPaths = new ArrayList<>();
+ findStorageGroupPaths(root, nodes, 1, "", storageGroupPaths, false);
+ return storageGroupPaths;
+ }
+
+ /**
+ * Get all storage group under given path
*
* @return a list contains all storage group names under give path
*/
@@ -640,22 +660,29 @@ public class MTree implements Serializable {
throw new IllegalPathException(prefixPath.getFullPath());
}
List<PartialPath> storageGroupPaths = new ArrayList<>();
- findStorageGroupPaths(root, nodes, 1, "", storageGroupPaths);
+ findStorageGroupPaths(root, nodes, 1, "", storageGroupPaths, true);
return storageGroupPaths;
}
/**
* Traverse the MTree to match all storage group with prefix path.
+ * When trying to find storage groups via a path, we divide into two cases:
+ * 1. This path is only regarded as a prefix, in other words, this path is
part of the result
+ * storage groups.
+ * 2. This path is a full path and we use this method to find its belonged
storage group.
+ * When prefixOnly is set to true, storage group paths in 1 is only added
into result,
+ * otherwise, both 1 and 2 are returned.
*
* @param node the current traversing node
* @param nodes split the prefix path with '.'
* @param idx the current index of array nodes
* @param parent current parent path
* @param storageGroupPaths store all matched storage group names
+ * @param prefixOnly only return storage groups that start with this
prefix path
*/
private void findStorageGroupPaths(MNode node, String[] nodes, int idx,
String parent,
- List<PartialPath> storageGroupPaths) {
- if (node instanceof StorageGroupMNode && idx >= nodes.length) {
+ List<PartialPath> storageGroupPaths, boolean prefixOnly) {
+ if (node instanceof StorageGroupMNode && (!prefixOnly || idx >=
nodes.length)) {
storageGroupPaths.add(node.getPartialPath());
return;
}
@@ -663,13 +690,14 @@ public class MTree implements Serializable {
if (!(PATH_WILDCARD).equals(nodeReg)) {
MNode next = node.getChild(nodeReg);
if (next != null) {
- findStorageGroupPaths(next, nodes, idx + 1,
- parent + node.getName() + PATH_SEPARATOR, storageGroupPaths);
+ findStorageGroupPaths(node.getChild(nodeReg), nodes, idx + 1,
+ parent + node.getName() + PATH_SEPARATOR, storageGroupPaths,
prefixOnly);
}
} else {
for (MNode child : node.getChildren().values()) {
findStorageGroupPaths(
- child, nodes, idx + 1, parent + node.getName() + PATH_SEPARATOR,
storageGroupPaths);
+ child, nodes, idx + 1, parent + node.getName() + PATH_SEPARATOR,
storageGroupPaths,
+ prefixOnly);
}
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
b/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
index 35dd7be..c5b49e9 100755
--- a/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
@@ -50,6 +50,11 @@ public class PartialPath extends Path implements
Comparable<Path> {
this.fullPath = path;
}
+ public PartialPath(String device, String measurement) throws
IllegalPathException {
+ this.fullPath = device + TsFileConstant.PATH_SEPARATOR + measurement;
+ this.nodes = MetaUtils.splitPathToDetachedPath(fullPath);
+ }
+
/**
* @param partialNodes nodes of a time series path
*/
@@ -87,6 +92,7 @@ public class PartialPath extends Path implements
Comparable<Path> {
int len = nodes.length;
this.nodes = Arrays.copyOf(nodes, nodes.length + otherNodes.length);
System.arraycopy(otherNodes, 0, nodes, len, otherNodes.length);
+ fullPath = String.join(TsFileConstant.PATH_SEPARATOR, nodes);
}
public PartialPath concatNode(String node) {
@@ -99,6 +105,49 @@ public class PartialPath extends Path implements
Comparable<Path> {
return nodes;
}
+ public int getNodeLength() {
+ return nodes.length;
+ }
+
+ public String getTailNode() {
+ if (nodes.length <= 0) {
+ return "";
+ }
+ return nodes[nodes.length - 1];
+ }
+
+ /**
+ * Construct a new PartialPath by resetting the prefix nodes to prefixPath
+ * @param prefixPath the prefix path used to replace current nodes
+ * @return A new PartialPath with altered prefix
+ */
+ public PartialPath alterPrefixPath(PartialPath prefixPath) {
+ String[] newNodes = Arrays.copyOf(nodes, Math.max(nodes.length,
prefixPath.getNodeLength()));
+ System.arraycopy(prefixPath.getNodes(), 0, newNodes, 0,
prefixPath.getNodeLength());
+ return new PartialPath(newNodes);
+ }
+
+ /**
+ * Test if this PartialPath matches a full path. rPath is supposed to be a
full timeseries path
+ * without wildcards.
+ * e.g. "root.sg.device.*" matches path "root.sg.device.s1"
+ * whereas it does not match "root.sg.device" and "root.sg.vehicle.s1"
+ * @param rPath a plain full path of a timeseries
+ * @return true if a successful match, otherwise return false
+ */
+ public boolean matchFullPath(PartialPath rPath) {
+ String[] rNodes = rPath.getNodes();
+ if (rNodes.length < nodes.length) {
+ return false;
+ }
+ for (int i = 0; i < nodes.length; i++) {
+ if (!nodes[i].equals(IoTDBConstant.PATH_WILDCARD) &&
!nodes[i].equals(rNodes[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Override
public String getFullPath() {
if (fullPath != null) {
@@ -167,7 +216,9 @@ public class PartialPath extends Path implements
Comparable<Path> {
return measurementAlias;
}
- public void setMeasurementAlias(String measurementAlias) {
this.measurementAlias = measurementAlias; }
+ public void setMeasurementAlias(String measurementAlias) {
+ this.measurementAlias = measurementAlias;
+ }
public String getTsAlias() {
return tsAlias;
diff --git a/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java
b/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java
index 12cf8f0..41ae412 100644
--- a/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java
@@ -367,7 +367,7 @@ public class StatMonitor implements IService {
for (Map.Entry<String, IStatistic> entry : statisticMap.entrySet()) {
for (String statParamName :
entry.getValue().getStatParamsHashMap().keySet()) {
if (temporaryStatList.contains(statParamName)) {
- fManager.delete(new PartialPath(entry.getKey()), statParamName,
Long.MIN_VALUE,
+ fManager.delete(new PartialPath(entry.getKey(), statParamName),
Long.MIN_VALUE,
currentTimeMillis - statMonitorRetainIntervalSec * 1000);
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 5f5b6d6..35fc394 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -710,19 +710,8 @@ public class PlanExecutor implements IPlanExecutor {
@Override
public void delete(DeletePlan deletePlan) throws QueryProcessException {
- try {
- Set<PartialPath> existingPaths = new HashSet<>();
- for (PartialPath p : deletePlan.getPaths()) {
- existingPaths.addAll(getPathsName(p));
- }
- if (existingPaths.isEmpty()) {
- throw new QueryProcessException("TimeSeries does not exist and its
data cannot be deleted");
- }
- for (PartialPath path : existingPaths) {
- delete(path, deletePlan.getDeleteStartTime(),
deletePlan.getDeleteEndTime());
- }
- } catch (MetadataException e) {
- throw new QueryProcessException(e);
+ for (PartialPath path : deletePlan.getPaths()) {
+ delete(path, deletePlan.getDeleteStartTime(),
deletePlan.getDeleteEndTime());
}
}
@@ -893,14 +882,8 @@ public class PlanExecutor implements IPlanExecutor {
@Override
public void delete(PartialPath path, long startTime, long endTime) throws
QueryProcessException {
- PartialPath deviceId = path.getDevicePath();
- String measurementId = path.getMeasurement();
try {
- if (!mManager.isPathExist(path)) {
- throw new QueryProcessException(
- String.format("Time series %s does not exist.",
path.getFullPath()));
- }
- StorageEngine.getInstance().delete(deviceId, measurementId, startTime,
endTime);
+ StorageEngine.getInstance().delete(path, startTime, endTime);
} catch (StorageEngineException e) {
throw new QueryProcessException(e);
}
@@ -1061,7 +1044,7 @@ public class PlanExecutor implements IPlanExecutor {
try {
List<String> failedNames = new LinkedList<>();
for (PartialPath path : deletePathList) {
- StorageEngine.getInstance().deleteTimeseries(path.getDevicePath(),
path.getMeasurement());
+ StorageEngine.getInstance().deleteTimeseries(path);
String failedTimeseries = mManager.deleteTimeseries(path);
if (!failedTimeseries.isEmpty()) {
failedNames.add(failedTimeseries);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
b/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
index e37d12b..863d4c3 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/context/QueryContext.java
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.iotdb.db.engine.modification.Modification;
import org.apache.iotdb.db.engine.modification.ModificationFile;
+import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
/**
@@ -60,10 +61,10 @@ public class QueryContext {
* Find the modifications of timeseries 'path' in 'modFile'. If they are not
in the cache, read
* them from 'modFile' and put then into the cache.
*/
- public List<Modification> getPathModifications(ModificationFile modFile,
String path) {
+ public List<Modification> getPathModifications(ModificationFile modFile,
PartialPath path) {
Map<String, List<Modification>> fileModifications =
filePathModCache.computeIfAbsent(modFile.getFilePath(), k -> new
ConcurrentHashMap<>());
- return fileModifications.computeIfAbsent(path, k -> {
+ return fileModifications.computeIfAbsent(path.getFullPath(), k -> {
List<Modification> allModifications =
fileModCache.get(modFile.getFilePath());
if (allModifications == null) {
allModifications = (List<Modification>) modFile.getModifications();
@@ -72,7 +73,7 @@ public class QueryContext {
List<Modification> finalPathModifications = new ArrayList<>();
if (!allModifications.isEmpty()) {
allModifications.forEach(modification -> {
- if (modification.getPathString().equals(path)) {
+ if (modification.getPath().matchFullPath(path)) {
finalPathModifications.add(modification);
}
});
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
b/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
index 20eff72..e196fde 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/reader/chunk/metadata/DiskChunkMetadataLoader.java
@@ -26,7 +26,6 @@ import org.apache.iotdb.db.query.context.QueryContext;
import org.apache.iotdb.db.query.reader.chunk.DiskChunkLoader;
import org.apache.iotdb.db.utils.QueryUtils;
import org.apache.iotdb.tsfile.file.metadata.ChunkMetadata;
-import org.apache.iotdb.tsfile.read.common.Path;
import org.apache.iotdb.tsfile.read.controller.IChunkMetadataLoader;
import org.apache.iotdb.tsfile.read.filter.basic.Filter;
import java.io.IOException;
@@ -71,14 +70,14 @@ public class DiskChunkMetadataLoader implements
IChunkMetadataLoader {
* @throws IOException
*/
@Override
- public void setDiskChunkLoader(List<ChunkMetadata> chunkMetadataList) throws
IOException {
+ public void setDiskChunkLoader(List<ChunkMetadata> chunkMetadataList) {
setDiskChunkLoader(chunkMetadataList, resource, seriesPath, context);
}
public static void setDiskChunkLoader(List<ChunkMetadata> chunkMetadataList,
- TsFileResource resource, Path seriesPath, QueryContext context) {
+ TsFileResource resource, PartialPath seriesPath, QueryContext context) {
List<Modification> pathModifications =
- context.getPathModifications(resource.getModFile(),
seriesPath.getFullPath());
+ context.getPathModifications(resource.getModFile(), seriesPath);
if (!pathModifications.isEmpty()) {
QueryUtils.modifyChunkMetaData(chunkMetadataList, pathModifications);
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
b/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
index 7f2f520..b3af734 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
@@ -109,7 +109,7 @@ public class FileLoaderUtils {
if (timeSeriesMetadata != null) {
List<Modification> pathModifications =
- context.getPathModifications(resource.getModFile(),
seriesPath.getFullPath());
+ context.getPathModifications(resource.getModFile(), seriesPath);
timeSeriesMetadata.setModified(!pathModifications.isEmpty());
if (timeSeriesMetadata.getStatistics().getStartTime() >
timeSeriesMetadata.getStatistics()
.getEndTime()) {
diff --git
a/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
b/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
index 8f9cbd4..d6bf865 100644
--- a/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
+++ b/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.iotdb.db.engine.memtable.IMemTable;
import org.apache.iotdb.db.engine.modification.Deletion;
import org.apache.iotdb.db.engine.modification.ModificationFile;
@@ -117,12 +118,14 @@ public class LogReplayer {
tempEndTimeMap.forEach((k, v) -> currentTsFileResource.updateEndTime(k,
v));
}
- private void replayDelete(DeletePlan deletePlan) throws IOException {
+ private void replayDelete(DeletePlan deletePlan) throws IOException,
MetadataException {
List<PartialPath> paths = deletePlan.getPaths();
for (PartialPath path : paths) {
- recoverMemTable
- .delete(path.getDevice(), path.getMeasurement(),
deletePlan.getDeleteStartTime(),
- deletePlan.getDeleteEndTime());
+ for (PartialPath device :
IoTDB.metaManager.getDevices(path.getDevicePath())) {
+ recoverMemTable
+ .delete(path, device, deletePlan.getDeleteStartTime(),
+ deletePlan.getDeleteEndTime());
+ }
modFile
.write(
new Deletion(path, versionController.nextVersion(),
deletePlan.getDeleteStartTime(),
diff --git
a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java
b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java
index 5d0ad9e..165fe6d 100644
---
a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java
@@ -107,10 +107,10 @@ public class DeletionFileNodeTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 30);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 30, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 30, 50);
SingleSeriesExpression expression = new SingleSeriesExpression(new
PartialPath(processorName + TsFileConstant.PATH_SEPARATOR +
measurements[5]), null);
@@ -143,9 +143,9 @@ public class DeletionFileNodeTest {
}
StorageEngine.getInstance().syncCloseAllProcessor();
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 40);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 40);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 30);
Modification[] realModifications = new Modification[]{
new Deletion(new PartialPath(processorName +
TsFileConstant.PATH_SEPARATOR + measurements[5]), 201, 50),
@@ -207,10 +207,10 @@ public class DeletionFileNodeTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 30);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 30, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 30, 50);
SingleSeriesExpression expression = new SingleSeriesExpression(new
PartialPath(processorName + TsFileConstant.PATH_SEPARATOR +
measurements[5]), null);
@@ -256,9 +256,9 @@ public class DeletionFileNodeTest {
}
StorageEngine.getInstance().syncCloseAllProcessor();
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 40);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 40);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 30);
Modification[] realModifications = new Modification[]{
new Deletion(new PartialPath(processorName +
TsFileConstant.PATH_SEPARATOR + measurements[5]), 301, 50),
diff --git
a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java
b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java
index be99831..a5b2530 100644
---
a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java
@@ -99,10 +99,10 @@ public class DeletionQueryTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 30);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 30, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 30, 50);
List<PartialPath> pathList = new ArrayList<>();
pathList.add(new PartialPath(processorName + TsFileConstant.PATH_SEPARATOR
+ measurements[3]));
@@ -138,9 +138,9 @@ public class DeletionQueryTest {
}
StorageEngine.getInstance().syncCloseAllProcessor();
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 40);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 40);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 30);
List<PartialPath> pathList = new ArrayList<>();
pathList.add(new PartialPath(processorName + TsFileConstant.PATH_SEPARATOR
+ measurements[3]));
@@ -187,10 +187,10 @@ public class DeletionQueryTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 30);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 30, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 30, 50);
List<PartialPath> pathList = new ArrayList<>();
pathList.add(new PartialPath(processorName + TsFileConstant.PATH_SEPARATOR
+ measurements[3]));
@@ -237,9 +237,9 @@ public class DeletionQueryTest {
}
StorageEngine.getInstance().syncCloseAllProcessor();
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 40);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 40);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 30);
List<PartialPath> pathList = new ArrayList<>();
pathList.add(new PartialPath(processorName + TsFileConstant.PATH_SEPARATOR
+ measurements[3]));
@@ -275,10 +275,10 @@ public class DeletionQueryTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 30);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 30, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 30, 50);
StorageEngine.getInstance().syncCloseAllProcessor();
@@ -290,10 +290,10 @@ public class DeletionQueryTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 250);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 250);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 230);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 230, 250);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 250);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 250);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 230);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 230, 250);
StorageEngine.getInstance().syncCloseAllProcessor();
@@ -305,10 +305,10 @@ public class DeletionQueryTest {
insertToStorageEngine(record);
}
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[3], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[4], 0, 50);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 0, 30);
- StorageEngine.getInstance().delete(new PartialPath(processorName),
measurements[5], 30, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[3]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[4]), 0, 50);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 0, 30);
+ StorageEngine.getInstance().delete(new PartialPath(processorName,
measurements[5]), 30, 50);
StorageEngine.getInstance().syncCloseAllProcessor();
diff --git
a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
index cfa7c64..bb649b0 100644
---
a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
@@ -39,6 +39,7 @@ import
org.apache.iotdb.db.engine.tsfilemanagement.TsFileManagementStrategy;
import org.apache.iotdb.db.exception.StorageGroupProcessorException;
import org.apache.iotdb.db.exception.WriteProcessException;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
@@ -98,7 +99,7 @@ public class StorageGroupProcessorTest {
@Test
public void testUnseqUnsealedDelete()
- throws WriteProcessException, IOException, IllegalPathException {
+ throws WriteProcessException, IOException, MetadataException {
TSRecord record = new TSRecord(10000, deviceId);
record.addTuple(DataPoint.getDataPoint(TSDataType.INT32, measurementId,
String.valueOf(1000)));
insertToStorageGroupProcessor(record);
@@ -120,7 +121,7 @@ public class StorageGroupProcessorTest {
insertToStorageGroupProcessor(record);
}
- processor.delete(new PartialPath(deviceId), measurementId, 0, 15L);
+ processor.delete(new PartialPath(deviceId, measurementId), 0, 15L);
List<TsFileResource> tsfileResourcesForQuery = new ArrayList<>();
for (TsFileProcessor tsfileProcessor :
processor.getWorkUnsequenceTsFileProcessor()) {
diff --git
a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessorTest.java
b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessorTest.java
index adaf93c..f3d3f0b 100644
---
a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessorTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessorTest.java
@@ -37,6 +37,7 @@ import
org.apache.iotdb.db.engine.version.SysTimeVersionController;
import org.apache.iotdb.db.exception.TsFileProcessorException;
import org.apache.iotdb.db.exception.WriteProcessException;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.query.context.QueryContext;
import org.apache.iotdb.db.utils.EnvironmentUtils;
@@ -83,7 +84,7 @@ public class TsFileProcessorTest {
}
@Test
- public void testWriteAndFlush() throws IOException, WriteProcessException,
IllegalPathException {
+ public void testWriteAndFlush() throws IOException, WriteProcessException,
MetadataException {
logger.info("testWriteAndFlush begin..");
processor = new TsFileProcessor(storageGroup,
SystemFileFactory.INSTANCE.getFile(filePath),
SysTimeVersionController.INSTANCE, this::closeTsFileProcessor,
@@ -134,7 +135,7 @@ public class TsFileProcessorTest {
@Test
public void testWriteAndRestoreMetadata()
- throws IOException, WriteProcessException, IllegalPathException {
+ throws IOException, WriteProcessException, MetadataException {
logger.info("testWriteAndRestoreMetadata begin..");
processor = new TsFileProcessor(storageGroup,
SystemFileFactory.INSTANCE.getFile(filePath),
SysTimeVersionController.INSTANCE, this::closeTsFileProcessor,
@@ -211,7 +212,7 @@ public class TsFileProcessorTest {
@Test
- public void testMultiFlush() throws IOException, WriteProcessException,
IllegalPathException {
+ public void testMultiFlush() throws IOException, WriteProcessException,
MetadataException {
logger.info("testWriteAndRestoreMetadata begin..");
processor = new TsFileProcessor(storageGroup,
SystemFileFactory.INSTANCE.getFile(filePath),
SysTimeVersionController.INSTANCE, this::closeTsFileProcessor,
@@ -246,7 +247,7 @@ public class TsFileProcessorTest {
}
@Test
- public void testWriteAndClose() throws IOException, WriteProcessException,
IllegalPathException {
+ public void testWriteAndClose() throws IOException, WriteProcessException,
MetadataException {
logger.info("testWriteAndRestoreMetadata begin..");
processor = new TsFileProcessor(storageGroup,
SystemFileFactory.INSTANCE.getFile(filePath),
SysTimeVersionController.INSTANCE, this::closeTsFileProcessor,
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MTreeTest.java
b/server/src/test/java/org/apache/iotdb/db/metadata/MTreeTest.java
index c5af5c4..fd5db9c 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MTreeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MTreeTest.java
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.iotdb.db.exception.metadata.AliasAlreadyExistException;
@@ -475,4 +476,24 @@ public class MTreeTest {
e.getMessage());
}
}
+
+ @Test
+ public void testSearchStorageGroup() throws MetadataException {
+ MTree root = new MTree();
+ String path1 = "root";
+ String sgPath1 = "root.vehicle";
+ root.setStorageGroup(new PartialPath(sgPath1));
+ assertTrue(root.isPathExist(new PartialPath(path1)));
+ try {
+ root.createTimeseries(new PartialPath("root.vehicle.d1.s1"),
TSDataType.INT32, TSEncoding.RLE,
+ TSFileDescriptor.getInstance().getConfig().getCompressor(),
Collections.emptyMap(), null);
+ root.createTimeseries(new PartialPath("root.vehicle.d1.s2"),
TSDataType.INT32, TSEncoding.RLE,
+ TSFileDescriptor.getInstance().getConfig().getCompressor(),
Collections.emptyMap(), null);
+ } catch (MetadataException e1) {
+ fail(e1.getMessage());
+ }
+
+ assertEquals(root.searchAllRelatedStorageGroups(new
PartialPath("root.vehicle.d1.s1")),
+ Arrays.asList(new PartialPath(sgPath1)));
+ }
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/metadata/PartialPathTest.java
b/server/src/test/java/org/apache/iotdb/db/metadata/PartialPathTest.java
index fb02d6f..4b77d44 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/PartialPathTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/PartialPathTest.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.metadata;
import java.util.Arrays;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.junit.After;
import org.junit.Assert;
@@ -68,7 +69,31 @@ public class PartialPathTest {
arr1[0] = "root";
arr1[1] = "sg1";
PartialPath a = new PartialPath(arr1);
- Assert.assertEquals("[root, sg1, d1]",
Arrays.toString(a.concatNode("d1").getNodes()));
+ String[] arr2 = new String[1];
+ arr2[0] = "d1";
+ a.concatPath(arr2);
+ Assert.assertEquals("[root, sg1, d1]", Arrays.toString(a.getNodes()));
+ Assert.assertEquals("root.sg1.d1", a.getFullPath());
+ }
+
+ @Test
+ public void testAlterPrefixPath() throws IllegalPathException {
+ PartialPath p1 = new PartialPath("root.sg1.d1.s1");
+ PartialPath p2 = p1.alterPrefixPath(new PartialPath("root.sg2"));
+ PartialPath p3 = p1.alterPrefixPath(new PartialPath("root.sg2.d1.d2.s3"));
+
+ Assert.assertEquals("root.sg2.d1.s1", p2.getFullPath());
+ Assert.assertEquals("root.sg2.d1.d2.s3", p3.getFullPath());
+ }
+
+ @Test
+ public void testMatchPath() throws IllegalPathException {
+ PartialPath p1 = new PartialPath("root.sg1.d1.*");
+
+ Assert.assertTrue(p1.matchFullPath(new PartialPath("root.sg1.d1.s2")));
+ Assert.assertFalse(p1.matchFullPath(new PartialPath("root.sg1.d1")));
+ Assert.assertFalse(p1.matchFullPath(new PartialPath("root.sg2.d1.*")));
+ Assert.assertFalse(p1.matchFullPath(new PartialPath("")));
}
}