This is an automated email from the ASF dual-hosted git repository.
geniuspig pushed a commit to branch optimize_path
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git
The following commit(s) were added to refs/heads/optimize_path by this push:
new 0e5b4f9 add method
0e5b4f9 is described below
commit 0e5b4f90a46db708b9aa6bdc8a712160c33fc2af
Author: zhutianci <[email protected]>
AuthorDate: Tue Jul 14 16:41:43 2020 +0800
add method
---
.../org/apache/iotdb/db/metadata/MManager.java | 94 ++++++++++-----
.../java/org/apache/iotdb/db/metadata/MTree.java | 132 +++++++++++++++++++++
.../org/apache/iotdb/db/metadata/MetaUtils.java | 24 ++++
.../iotdb/db/qp/physical/crud/InsertRowPlan.java | 7 +-
.../iotdb/db/qp/strategy/PhysicalGenerator.java | 2 +-
.../apache/iotdb/db/utils/RandomDeleteCache.java | 17 ++-
6 files changed, 232 insertions(+), 44 deletions(-)
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 75cf379..5232485 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
@@ -143,20 +143,7 @@ public class MManager {
isRecovering = true;
int cacheSize = config.getmManagerCacheSize();
- mNodeCache = new RandomDeleteCache<String, MNode>(cacheSize) {
-
- @Override
- public MNode loadObjectByKey(String key) throws CacheException {
- lock.readLock().lock();
- try {
- return mtree.getNodeByPathWithStorageGroupCheck(key);
- } catch (MetadataException e) {
- throw new CacheException(e);
- } finally {
- lock.readLock().unlock();
- }
- }
- };
+ mNodeCache = new RandomDeleteCache<String, MNode>(cacheSize) {};
int remoteCacheSize = config.getmRemoteSchemaCacheSize();
mRemoteSchemaCache = new LRUCache<String,
MeasurementSchema>(remoteCacheSize) {
@@ -1084,48 +1071,86 @@ public class MManager {
* @param path path
*/
public MNode getDeviceNodeWithAutoCreateAndReadLock(
- String path, boolean autoCreateSchema, int sgLevel) throws
MetadataException {
+ String path, List<String> nodes, boolean autoCreateSchema, int sgLevel)
throws MetadataException {
lock.readLock().lock();
MNode node = null;
- boolean shouldSetStorageGroup;
try {
node = mNodeCache.get(path);
+ if (node == null) {
+ node = mtree.getNodeByNodesWithStorageGroupCheck(nodes);
+ if (path == null) {
+ mNodeCache.put(node.getFullPath(), node);
+ } else {
+ mNodeCache.put(path, node);
+ }
+ }
return node;
- } catch (CacheException e) {
+ } catch (Exception e) {
if (!autoCreateSchema) {
throw new PathNotExistException(path);
}
+ if (e.getCause() instanceof StorageGroupNotSetException) {
+ String storageGroupName = MetaUtils.getStorageGroupNameByLevel(path,
sgLevel);
+ setStorageGroup(storageGroupName);
+ node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
+ return node;
+ }
+ if (e.getCause() instanceof StorageGroupAlreadySetException) {
+ node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
+ return node;
+ }
+ return node;
} finally {
if (node != null) {
node.readLock();
}
lock.readLock().unlock();
}
+ }
- lock.writeLock().lock();
+ /**
+ * get device node, if the storage group is not set, create it when
autoCreateSchema is true <p>
+ * (we develop this method as we need to get the node's lock after we get
the lock.writeLock())
+ *
+ * <p>!!!!!!Attention!!!!! must call the return node's readUnlock() if you
call this method.
+ *
+ * @param path path
+ */
+ public MNode getDeviceNodeWithAutoCreateAndReadLock(
+ String path, boolean autoCreateSchema, int sgLevel) throws
MetadataException {
+ lock.readLock().lock();
+ MNode node = null;
try {
- try {
- node = mNodeCache.get(path);
- return node;
- } catch (CacheException e) {
- shouldSetStorageGroup = e.getCause() instanceof
StorageGroupNotSetException;
+ node = mNodeCache.get(path);
+ if (node == null) {
+ node = mtree.getNodeByPathWithStorageGroupCheck(path);
+ if (path == null) {
+ mNodeCache.put(node.getFullPath(), node);
+ } else {
+ mNodeCache.put(path, node);
+ }
}
-
- if (shouldSetStorageGroup) {
+ return node;
+ } catch (Exception e) {
+ if (!autoCreateSchema) {
+ throw new PathNotExistException(path);
+ }
+ if (e.getCause() instanceof StorageGroupNotSetException) {
String storageGroupName = MetaUtils.getStorageGroupNameByLevel(path,
sgLevel);
setStorageGroup(storageGroupName);
+ node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
+ return node;
+ }
+ if (e.getCause() instanceof StorageGroupAlreadySetException) {
+ node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
+ return node;
}
- node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
- return node;
- } catch (StorageGroupAlreadySetException e) {
- // ignore set storage group concurrently
- node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
return node;
} finally {
if (node != null) {
node.readLock();
}
- lock.writeLock().unlock();
+ lock.readLock().unlock();
}
}
@@ -1137,13 +1162,18 @@ public class MManager {
path, config.isAutoCreateSchemaEnabled(),
config.getDefaultStorageGroupLevel());
}
+ public MNode getDeviceNodeWithAutoCreateAndReadLock(String path,
List<String> nodes) throws MetadataException {
+ return getDeviceNodeWithAutoCreateAndReadLock(
+ path, nodes, config.isAutoCreateSchemaEnabled(),
config.getDefaultStorageGroupLevel());
+ }
+
public MNode getDeviceNode(String path) throws MetadataException {
lock.readLock().lock();
MNode node;
try {
node = mNodeCache.get(path);
return node;
- } catch (CacheException e) {
+ } catch (Exception e) {
throw new PathNotExistException(path);
} finally {
lock.readLock().unlock();
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 d3921f7..e132c07 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
@@ -237,6 +237,40 @@ public class MTree implements Serializable {
}
/**
+ * Set storage group. Make sure check seriesPath before setting storage group
+ *
+ * @param nodeNames nodeNames
+ */
+ void setStorageGroup(List<String> nodeNames) throws MetadataException {
+ MNode cur = root;
+ if (nodeNames.size() <= 1 || !nodeNames.get(0).equals(root.getName())) {
+ throw new IllegalPathException(nodeNames.toString());
+ }
+ int i = 1;
+ // e.g., path = root.a.b.sg, create internal nodes for a, b
+ while (i < nodeNames.size() - 1) {
+ MNode temp = cur.getChild(nodeNames.get(i));
+ if (temp == null) {
+ cur.addChild(nodeNames.get(i), new MNode(cur, nodeNames.get(i)));
+ } else if (temp instanceof StorageGroupMNode) {
+ // before set storage group, check whether the exists or not
+ throw new StorageGroupAlreadySetException(temp.getFullPath());
+ }
+ cur = cur.getChild(nodeNames.get(i));
+ i++;
+ }
+ if (cur.hasChild(nodeNames.get(i))) {
+ // node b has child sg
+ throw new StorageGroupAlreadySetException(nodeNames.toString());
+ } else {
+ StorageGroupMNode storageGroupMNode =
+ new StorageGroupMNode(
+ cur, nodeNames.get(i),
IoTDBDescriptor.getInstance().getConfig().getDefaultTTL());
+ cur.addChild(nodeNames.get(i), storageGroupMNode);
+ }
+ }
+
+ /**
* Delete a storage group
*/
List<MeasurementMNode> deleteStorageGroup(String path) throws
MetadataException {
@@ -273,6 +307,42 @@ public class MTree implements Serializable {
}
/**
+ * Delete a storage group
+ */
+ List<MeasurementMNode> deleteStorageGroup(List<String> nodes) throws
MetadataException {
+ MNode cur = getNodeByNodes(nodes);
+ if (!(cur instanceof StorageGroupMNode)) {
+ throw new StorageGroupNotSetException(nodes.toString());
+ }
+ // Suppose current system has root.a.b.sg1, root.a.sg2, and delete
root.a.b.sg1
+ // delete the storage group node sg1
+ cur.getParent().deleteChild(cur.getName());
+
+ // collect all the LeafMNode in this storage group
+ List<MeasurementMNode> leafMNodes = new LinkedList<>();
+ Queue<MNode> queue = new LinkedList<>();
+ queue.add(cur);
+ while (!queue.isEmpty()) {
+ MNode node = queue.poll();
+ for (MNode child : node.getChildren().values()) {
+ if (child instanceof MeasurementMNode) {
+ leafMNodes.add((MeasurementMNode) child);
+ } else {
+ queue.add(child);
+ }
+ }
+ }
+
+ cur = cur.getParent();
+ // delete node b while retain root.a.sg2
+ while (!IoTDBConstant.PATH_ROOT.equals(cur.getName()) &&
cur.getChildren().size() == 0) {
+ cur.getParent().deleteChild(cur.getName());
+ cur = cur.getParent();
+ }
+ return leafMNodes;
+ }
+
+ /**
* Check whether path is storage group or not
*
* <p>e.g., path = root.a.b.sg. if nor a and b is StorageGroupMNode and sg
is a StorageGroupMNode
@@ -375,6 +445,37 @@ public class MTree implements Serializable {
}
/**
+ * Get node by path with storage group check If storage group is not set,
+ * StorageGroupNotSetException will be thrown
+ */
+ MNode getNodeByNodesWithStorageGroupCheck(List<String> nodes) throws
MetadataException {
+ boolean storageGroupChecked = false;
+ if (nodes.isEmpty() || !nodes.get(0).equals(root.getName())) {
+ throw new IllegalPathException(nodes.toString());
+ }
+
+ MNode cur = root;
+ for (int i = 1; i < nodes.size(); i++) {
+ if (!cur.hasChild(nodes.get(i))) {
+ if (!storageGroupChecked) {
+ throw new StorageGroupNotSetException(nodes.toString());
+ }
+ throw new PathNotExistException(nodes.toString());
+ }
+ cur = cur.getChild(nodes.get(i));
+
+ if (cur instanceof StorageGroupMNode) {
+ storageGroupChecked = true;
+ }
+ }
+
+ if (!storageGroupChecked) {
+ throw new StorageGroupNotSetException(nodes.toString());
+ }
+ return cur;
+ }
+
+ /**
* Get storage group node, if the give path is not a storage group, throw
exception
*/
StorageGroupMNode getStorageGroupNode(String path) throws MetadataException {
@@ -387,6 +488,18 @@ public class MTree implements Serializable {
}
/**
+ * Get storage group node, if the give path is not a storage group, throw
exception
+ */
+ StorageGroupMNode getStorageGroupNode(List<String> nodes) throws
MetadataException {
+ MNode node = getNodeByNodes(nodes);
+ if (node instanceof StorageGroupMNode) {
+ return (StorageGroupMNode) node;
+ } else {
+ throw new StorageGroupNotSetException(nodes.toString());
+ }
+ }
+
+ /**
* Get node by the path
*
* @return last node in given seriesPath
@@ -407,6 +520,25 @@ public class MTree implements Serializable {
}
/**
+ * Get node by the path
+ *
+ * @return last node in given seriesPath
+ */
+ MNode getNodeByNodes(List<String> nodes) throws MetadataException {
+ if (nodes.isEmpty() || !nodes.get(0).equals(root.getName())) {
+ throw new IllegalPathException(nodes.toString());
+ }
+ MNode cur = root;
+ for (int i = 1; i < nodes.size(); i++) {
+ if (!cur.hasChild(nodes.get(i))) {
+ throw new PathNotExistException(nodes.toString());
+ }
+ cur = cur.getChild(nodes.get(i));
+ }
+ return cur;
+ }
+
+ /**
* Get all storage groups under the given path
*
* @return storage group list
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
index 05f7374..7108285 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.metadata;
import static org.apache.iotdb.db.conf.IoTDBConstant.PATH_WILDCARD;
import java.util.Arrays;
+import java.util.List;
import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
@@ -60,6 +61,10 @@ public class MetaUtils {
return idx >= nodes.length ? PATH_WILDCARD : nodes[idx];
}
+ public static List<String> getDeviceNodeNames(String path) {
+ return Arrays.asList(path.split(PATH_SEPARATOR));
+ }
+
/**
* Get storage group name when creating schema automatically is enable
*
@@ -79,4 +84,23 @@ public class MetaUtils {
}
return storageGroupName.toString();
}
+
+ /**
+ * Get storage group name when creating schema automatically is enable
+ *
+ * e.g., nodes = [root, a, b, c] and level = 1, return [root, a]
+ *
+ * @param nodeNames nodeNames
+ * @param level level
+ */
+ public static List<String> getStorageGroupNodesByLevel(List<String>
nodeNames, int level) throws MetadataException {
+ if (nodeNames.size() <= level ||
!nodeNames.get(0).equals(IoTDBConstant.PATH_ROOT)) {
+ throw new IllegalPathException(nodeNames.toString());
+ }
+ for(int i = level + 1; nodeNames.size() > level; i--) {
+ nodeNames.remove(i);
+ }
+ return nodeNames;
+ }
+
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
index 0bef4f8..1d1e584 100644
---
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
+++
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
@@ -51,6 +51,7 @@ public class InsertRowPlan extends InsertPlan {
private long time;
private Object[] values;
+ private List<String> deviceNodes;
// if isNeedInferType is true, the values must be String[], so we could
infer types from them
// if values is object[], we could use the raw type of them, and we should
set this to false
@@ -111,20 +112,22 @@ public class InsertRowPlan extends InsertPlan {
}
}
- public InsertRowPlan(String deviceId, long insertTime, String[]
measurementList,
+ public InsertRowPlan(List<String> deviceNodes, String deviceId, long
insertTime, String[] measurementList,
TSDataType[] dataTypes, Object[] insertValues) {
super(Operator.OperatorType.INSERT);
this.time = insertTime;
+ this.deviceNodes = deviceNodes;
this.deviceId = deviceId;
this.measurements = measurementList;
this.dataTypes = dataTypes;
this.values = insertValues;
}
- public InsertRowPlan(String deviceId, long insertTime, String[]
measurementList,
+ public InsertRowPlan(List<String> deviceNodes, String deviceId, long
insertTime, String[] measurementList,
String[] insertValues) {
super(Operator.OperatorType.INSERT);
this.time = insertTime;
+ this.deviceNodes = deviceNodes;
this.deviceId = deviceId;
this.measurements = measurementList;
this.dataTypes = new TSDataType[measurements.length];
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index efce1a3..7c9272c 100644
---
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -177,7 +177,7 @@ public class PhysicalGenerator {
"For Insert command, cannot specified more than one seriesPath:
" + paths);
}
- return new InsertRowPlan(paths.get(0).getFullPath(), insert.getTime(),
+ return new InsertRowPlan(paths.get(0).getNodes(), insert.getTime(),
insert.getMeasurementList(), insert.getValueList());
case MERGE:
if (operator.getTokenIntType() == SQLConstant.TOK_FULL_MERGE) {
diff --git
a/server/src/main/java/org/apache/iotdb/db/utils/RandomDeleteCache.java
b/server/src/main/java/org/apache/iotdb/db/utils/RandomDeleteCache.java
index 90921ce..7ae70d6 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/RandomDeleteCache.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/RandomDeleteCache.java
@@ -28,20 +28,21 @@ public abstract class RandomDeleteCache<K, V> implements
Cache<K, V> {
private int cacheSize;
private Map<K, V> cache;
- public RandomDeleteCache(int cacheSize) {
+ protected RandomDeleteCache(int cacheSize) {
this.cacheSize = cacheSize;
this.cache = new ConcurrentHashMap<>();
}
@Override
- public V get(K key) throws CacheException {
- V v = cache.get(key);
- if (v == null) {
+ public V get(K key) {
+ return cache.get(key);
+ }
+
+ public void put(K key, V value) {
+ cache.put(key, value);
+ if(cache.get(key) == null) {
randomRemoveObjectIfCacheIsFull();
- cache.put(key, loadObjectByKey(key));
- v = cache.get(key);
}
- return v;
}
private void randomRemoveObjectIfCacheIsFull() {
@@ -58,8 +59,6 @@ public abstract class RandomDeleteCache<K, V> implements
Cache<K, V> {
cache.remove(key);
}
- public abstract V loadObjectByKey(K key) throws CacheException;
-
public void removeObject(K key) {
cache.remove(key);
}