This is an automated email from the ASF dual-hosted git repository.
kangrong pushed a commit to branch f_index_dev
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/f_index_dev by this push:
new aef6776 fix bug in add and remove index
aef6776 is described below
commit aef6776ae4e000e9f573bbd9f57e29b5dfe49be4
Author: kr11 <3095717866.com>
AuthorDate: Mon May 17 13:15:27 2021 +0800
fix bug in add and remove index
---
.../org/apache/iotdb/db/index/IndexManager.java | 13 +-
.../org/apache/iotdb/db/index/IndexProcessor.java | 7 +-
.../iotdb/db/index/router/ProtoIndexRouter.java | 80 ++++++++----
.../db/index/router/ProtoIndexRouterTest.java | 144 +++++++++++++++++----
4 files changed, 189 insertions(+), 55 deletions(-)
diff --git a/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
b/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
index 0216565..41c7f12 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
@@ -76,6 +76,11 @@ public class IndexManager implements IndexManagerMBean,
IService {
private final String indexDataDirPath;
private final IIndexRouter router;
+ @TestOnly
+ public CreateIndexProcessorFunc getCreateIndexProcessorFunc() {
+ return createIndexProcessorFunc;
+ }
+
/** A function interface to construct an index processor. */
private CreateIndexProcessorFunc createIndexProcessorFunc;
@@ -102,11 +107,15 @@ public class IndexManager implements IndexManagerMBean,
IService {
* @param indexType the type of index
* @return the feature directory path for this index.
*/
- private String getFeatureFileDirectory(PartialPath path, IndexType
indexType) {
+ public String getFeatureFileDirectory(PartialPath path, IndexType indexType)
{
return IndexUtils.removeIllegalStarInDir(
indexDataDirPath + File.separator + path.getFullPath() +
File.separator + indexType);
}
+ public String getIndexDirectory() {
+ return indexDataDirPath;
+ }
+
/**
* Given an IndexSeries, return its data file path (unused currently).
*
@@ -114,7 +123,7 @@ public class IndexManager implements IndexManagerMBean,
IService {
* @param indexType the type of index
* @return the feature directory path for this index.
*/
- private String getIndexDataDirectory(PartialPath path, IndexType indexType) {
+ public String getIndexDataDirectory(PartialPath path, IndexType indexType) {
return getFeatureFileDirectory(path, indexType);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
b/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
index 4548674..c1e821d 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
@@ -37,6 +37,7 @@ import org.apache.iotdb.db.metadata.MManager;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.query.context.QueryContext;
import org.apache.iotdb.db.service.IoTDB;
+import org.apache.iotdb.db.utils.FileUtils;
import org.apache.iotdb.db.utils.datastructure.TVList;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
@@ -279,7 +280,7 @@ public class IndexProcessor implements
Comparable<IndexProcessor> {
closed = true;
if (deleteFiles) {
File dir = IndexUtils.getIndexFile(indexSeriesDirPath);
- dir.delete();
+ FileUtils.deleteDirectory(dir);
}
} finally {
lock.writeLock().unlock();
@@ -497,9 +498,11 @@ public class IndexProcessor implements
Comparable<IndexProcessor> {
}
// remove index file directories
File dir = IndexUtils.getIndexFile(getIndexDir(indexType));
- dir.delete();
+ FileUtils.deleteDirectory(dir);
allPathsIndexMap.remove(indexType);
+ indexLockMap.remove(indexType);
usableMap.remove(indexType);
+ previousDataBufferMap.remove(indexType);
}
}
} finally {
diff --git
a/server/src/main/java/org/apache/iotdb/db/index/router/ProtoIndexRouter.java
b/server/src/main/java/org/apache/iotdb/db/index/router/ProtoIndexRouter.java
index 3b55dc7..021b17d 100644
---
a/server/src/main/java/org/apache/iotdb/db/index/router/ProtoIndexRouter.java
+++
b/server/src/main/java/org/apache/iotdb/db/index/router/ProtoIndexRouter.java
@@ -206,12 +206,14 @@ public class ProtoIndexRouter implements IIndexRouter {
partialPath.toLowerCase();
if (partialPath.isFullPath()) {
String fullPath = partialPath.getFullPath();
- if (!fullPathProcessorMap.containsKey(fullPath)) {
+ if (!fullPathProcessorMap.containsKey(fullPath)
+ ||
!fullPathProcessorMap.get(fullPath).infos.containsKey(indexType)) {
throw new QueryIndexException("haven't create index on " + fullPath);
}
struct = fullPathProcessorMap.get(fullPath);
} else {
- if (!wildCardProcessorMap.containsKey(partialPath)) {
+ if (!wildCardProcessorMap.containsKey(partialPath)
+ ||
!wildCardProcessorMap.get(partialPath).infos.containsKey(indexType)) {
throw new QueryIndexException("haven't create index on " +
partialPath);
}
struct = wildCardProcessorMap.get(partialPath);
@@ -237,7 +239,9 @@ public class ProtoIndexRouter implements IIndexRouter {
// TODO prefixPath must be "prefix", i.e. ending with wildcard:
root.XX.XX.*
// the wildcard match is costly. We'd move router into MManager
Map<PartialPath, Map<IndexType, IndexInfo>> res = new HashMap<>();
- if (prefixPath != null) prefixPath.toLowerCase();
+ if (prefixPath != null) {
+ prefixPath.toLowerCase();
+ }
wildCardProcessorMap.forEach(
(indexSeries, struct) -> {
if (prefixPath == null || prefixPath.matchFullPath(indexSeries)) {
@@ -273,7 +277,12 @@ public class ProtoIndexRouter implements IIndexRouter {
lock.writeLock().lock();
IndexType indexType = indexInfo.getIndexType();
// record the relationship between storage group and the
- StorageGroupMNode storageGroupMNode =
mManager.getStorageGroupNodeByPath(partialPath);
+ StorageGroupMNode storageGroupMNode;
+ try {
+ storageGroupMNode = mManager.getStorageGroupNodeByPath(partialPath);
+ } catch (NullPointerException e) {
+ throw new MetadataException("please set storage group before create
index");
+ }
String storageGroupPath = storageGroupMNode.getPartialPath().getFullPath();
// add to pathMap
try {
@@ -286,7 +295,12 @@ public class ProtoIndexRouter implements IIndexRouter {
fullPathProcessorMap.put(
fullPath, new IndexProcessorStruct(processor, partialPath,
infoMap));
} else {
- fullPathProcessorMap.get(fullPath).infos.put(indexType, indexInfo);
+ Map<IndexType, IndexInfo> infoMap =
fullPathProcessorMap.get(fullPath).infos;
+ if (infoMap.containsKey(indexType)) {
+ // nothing to do, throw exception
+ throw new MetadataException(indexType + " has already been set on
" + fullPath);
+ }
+ infoMap.put(indexType, indexInfo);
}
IndexProcessorStruct pair = fullPathProcessorMap.get(fullPath);
pair.processor.refreshSeriesIndexMapFromMManager(pair.infos);
@@ -312,7 +326,12 @@ public class ProtoIndexRouter implements IIndexRouter {
wildCardProcessorMap.put(
partialPath, new IndexProcessorStruct(processor,
representativePath, infoMap));
} else {
- wildCardProcessorMap.get(partialPath).infos.put(indexType,
indexInfo);
+ Map<IndexType, IndexInfo> infoMap =
wildCardProcessorMap.get(partialPath).infos;
+ if (infoMap.containsKey(indexType)) {
+ // nothing to do, throw exception
+ throw new MetadataException(indexType + " has already been set on
" + partialPath);
+ }
+ infoMap.put(indexType, indexInfo);
}
IndexProcessorStruct pair = wildCardProcessorMap.get(partialPath);
pair.processor.refreshSeriesIndexMapFromMManager(pair.infos);
@@ -344,39 +363,54 @@ public class ProtoIndexRouter implements IIndexRouter {
// only the pair.left (indexType map) will be updated.
lock.writeLock().lock();
// record the relationship between storage group and the index processors
- StorageGroupMNode storageGroupMNode =
mManager.getStorageGroupNodeByPath(partialPath);
+ StorageGroupMNode storageGroupMNode;
+ try {
+ storageGroupMNode = mManager.getStorageGroupNodeByPath(partialPath);
+ } catch (NullPointerException e) {
+ throw new MetadataException("no storage group, remove nothing");
+ }
String storageGroupPath = storageGroupMNode.getPartialPath().getFullPath();
// remove from pathMap
+ boolean actualRemove = false;
try {
if (partialPath.isFullPath()) {
String fullPath = partialPath.getFullPath();
if (fullPathProcessorMap.containsKey(fullPath)) {
IndexProcessorStruct pair = fullPathProcessorMap.get(fullPath);
- pair.infos.remove(indexType);
- pair.processor.refreshSeriesIndexMapFromMManager(pair.infos);
- if (pair.infos.isEmpty()) {
- sgToFullPathMap.get(storageGroupPath).remove(fullPath);
- fullPathProcessorMap.remove(fullPath);
- pair.representativePath = null;
- pair.processor.close(true);
- pair.processor = null;
+ if (pair.infos.containsKey(indexType)) {
+ pair.infos.remove(indexType);
+ pair.processor.refreshSeriesIndexMapFromMManager(pair.infos);
+ if (pair.infos.isEmpty()) {
+ sgToFullPathMap.get(storageGroupPath).remove(fullPath);
+ fullPathProcessorMap.remove(fullPath);
+ pair.representativePath = null;
+ pair.processor.close(true);
+ pair.processor = null;
+ }
+ actualRemove = true;
}
}
} else {
if (wildCardProcessorMap.containsKey(partialPath)) {
IndexProcessorStruct pair = wildCardProcessorMap.get(partialPath);
- pair.infos.remove(indexType);
- pair.processor.refreshSeriesIndexMapFromMManager(pair.infos);
- if (pair.infos.isEmpty()) {
- sgToWildCardPathMap.get(storageGroupPath).remove(partialPath);
- wildCardProcessorMap.remove(partialPath);
- pair.representativePath = null;
- pair.processor.close(true);
- pair.processor = null;
+ if (pair.infos.containsKey(indexType)) {
+ pair.infos.remove(indexType);
+ pair.processor.refreshSeriesIndexMapFromMManager(pair.infos);
+ if (pair.infos.isEmpty()) {
+ sgToWildCardPathMap.get(storageGroupPath).remove(partialPath);
+ wildCardProcessorMap.remove(partialPath);
+ pair.representativePath = null;
+ pair.processor.close(true);
+ pair.processor = null;
+ }
+ actualRemove = true;
}
}
}
+ if (!actualRemove) {
+ throw new MetadataException(indexType + " hasn't been created on " +
partialPath);
+ }
serialize(false);
} finally {
lock.writeLock().unlock();
diff --git
a/server/src/test/java/org/apache/iotdb/db/index/router/ProtoIndexRouterTest.java
b/server/src/test/java/org/apache/iotdb/db/index/router/ProtoIndexRouterTest.java
index 86b577b..441623d 100644
---
a/server/src/test/java/org/apache/iotdb/db/index/router/ProtoIndexRouterTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/index/router/ProtoIndexRouterTest.java
@@ -17,14 +17,15 @@
*/
package org.apache.iotdb.db.index.router;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.index.IndexProcessor;
+import org.apache.iotdb.db.index.IndexManager;
import org.apache.iotdb.db.index.common.IndexInfo;
+import org.apache.iotdb.db.index.common.IndexType;
import org.apache.iotdb.db.index.common.func.CreateIndexProcessorFunc;
import org.apache.iotdb.db.metadata.MManager;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.utils.EnvironmentUtils;
-import org.apache.iotdb.db.utils.FileUtils;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
@@ -56,10 +57,10 @@ public class ProtoIndexRouterTest {
private static final String direction3 = "root.wind2.3.direction";
private static final String index_sub = speed1;
private static final String index_full = "root.wind2.*.direction";
- private IndexInfo infoFull;
- private IndexInfo infoSub;
- private CreateIndexProcessorFunc fakeCreateFunc;
- private IndexInfo infoFull2;
+ private IndexInfo infoFull_RTREE;
+ private IndexInfo infoSub_ELB;
+ private CreateIndexProcessorFunc createFunc;
+ private IndexInfo infoFull2_NO_INDEX;
private void prepareMManager() throws MetadataException {
MManager mManager = MManager.getInstance();
@@ -98,43 +99,44 @@ public class ProtoIndexRouterTest {
props_full.put(PAA_DIM, "5");
Map<String, String> props_full2 = new HashMap<>();
props_full2.put(PAA_DIM, "10");
- this.infoSub = new IndexInfo(ELB_INDEX, 0, props_sub);
- this.infoFull = new IndexInfo(RTREE_PAA, 5, props_full);
- this.infoFull2 = new IndexInfo(NO_INDEX, 10, props_full2);
- this.fakeCreateFunc =
- (indexSeries, indexInfoMap) ->
- new IndexProcessor(
- indexSeries,
- testRouterDir + File.separator + "index_fake_" + indexSeries,
- indexInfoMap);
+ this.infoSub_ELB = new IndexInfo(ELB_INDEX, 0, props_sub);
+ this.infoFull_RTREE = new IndexInfo(RTREE_PAA, 5, props_full);
+ this.infoFull2_NO_INDEX = new IndexInfo(NO_INDEX, 10, props_full2);
+ this.createFunc = IndexManager.getInstance().getCreateIndexProcessorFunc();
+ // (indexSeries, indexInfoMap) ->
+ // new IndexProcessor(
+ // indexSeries,
+ // IndexManager.getInstance().getIndexDirectory() +
File.separator +
+ // "index_fake_" + indexSeries,
+ // indexInfoMap);
}
- private static final String testRouterDir = "test_protoIndexRouter";
+ // private static final String testRouterDir = "test_protoIndexRouter";
@Before
public void setUp() throws Exception {
EnvironmentUtils.envSetUp();
- if (!new File(testRouterDir).exists()) {
- new File(testRouterDir).mkdirs();
- }
+ // if (!new File(testRouterDir).exists()) {
+ // new File(testRouterDir).mkdirs();
+ // }
}
@After
public void tearDown() throws Exception {
EnvironmentUtils.cleanEnv();
- if (new File(testRouterDir).exists()) {
- FileUtils.deleteDirectory(new File(testRouterDir));
- }
+ // if (new File(testRouterDir).exists()) {
+ // FileUtils.deleteDirectory(new File(testRouterDir));
+ // }
}
@Test
public void testBasic() throws MetadataException, IOException {
prepareMManager();
- ProtoIndexRouter router = new ProtoIndexRouter(testRouterDir);
+ ProtoIndexRouter router = new
ProtoIndexRouter(IndexManager.getInstance().getIndexDirectory());
- router.addIndexIntoRouter(new PartialPath(index_sub), infoSub,
fakeCreateFunc, true);
- router.addIndexIntoRouter(new PartialPath(index_full), infoFull,
fakeCreateFunc, true);
- router.addIndexIntoRouter(new PartialPath(index_full), infoFull2,
fakeCreateFunc, true);
+ router.addIndexIntoRouter(new PartialPath(index_sub), infoSub_ELB,
createFunc, true);
+ router.addIndexIntoRouter(new PartialPath(index_full), infoFull_RTREE,
createFunc, true);
+ router.addIndexIntoRouter(new PartialPath(index_full), infoFull2_NO_INDEX,
createFunc, true);
// System.out.println(router.toString());
Assert.assertEquals(
"<{NO_INDEX=[type: NO_INDEX, time: 10, props: {PAA_DIM=10}],
RTREE_PAA=[type: RTREE_PAA, time: 5, props: {PAA_DIM=5}]}\n"
@@ -166,8 +168,8 @@ public class ProtoIndexRouterTest {
router.serialize(true);
Assert.assertEquals("", router.toString());
- IIndexRouter newRouter = new ProtoIndexRouter(testRouterDir);
- newRouter.deserializeAndReload(fakeCreateFunc);
+ IIndexRouter newRouter = new
ProtoIndexRouter(IndexManager.getInstance().getIndexDirectory());
+ newRouter.deserializeAndReload(createFunc);
Assert.assertEquals(
"<{NO_INDEX=[type: NO_INDEX, time: 10, props: {PAA_DIM=10}],
RTREE_PAA=[type: RTREE_PAA, time: 5, props: {PAA_DIM=5}]}\n"
+ "root.wind2.*.direction: {NO_INDEX=NO_INDEX,
RTREE_PAA=nMax:50,nMin:2,dim:4,seedsPicker:LINEARinner:0,leaf:1,item:0;\n"
@@ -194,4 +196,90 @@ public class ProtoIndexRouterTest {
newRouter.removeIndexFromRouter(new PartialPath(index_sub), ELB_INDEX);
Assert.assertEquals("", newRouter.toString());
}
+
+ @Test
+ public void testDuplicateAdd() throws MetadataException {
+ prepareMManager();
+ ProtoIndexRouter router = new
ProtoIndexRouter(IndexManager.getInstance().getIndexDirectory());
+
+ router.addIndexIntoRouter(new PartialPath(index_sub), infoSub_ELB,
createFunc, true);
+ router.addIndexIntoRouter(new PartialPath(index_full), infoFull_RTREE,
createFunc, true);
+ router.addIndexIntoRouter(new PartialPath(index_full), infoFull2_NO_INDEX,
createFunc, true);
+ try {
+ router.addIndexIntoRouter(new PartialPath(index_full),
infoFull2_NO_INDEX, createFunc, true);
+ Assert.fail();
+ } catch (MetadataException e) {
+ Assert.assertEquals(
+ "NO_INDEX has already been set on root.wind2.*.direction",
e.getMessage());
+ }
+ try {
+ router.addIndexIntoRouter(new PartialPath(index_sub), infoSub_ELB,
createFunc, true);
+ Assert.fail();
+ } catch (MetadataException e) {
+ Assert.assertEquals(
+ "ELB_INDEX has already been set on root.wind1.azq01.speed",
e.getMessage());
+ }
+ // System.out.println(router.toString());
+ }
+
+ private File getIndexDirFile(String path, IndexType indexType) throws
IllegalPathException {
+ return new File(
+ IndexManager.getInstance().getIndexDataDirectory(new
PartialPath(path), indexType));
+ }
+
+ @Test
+ public void testDuplicateDrop() throws MetadataException, IOException {
+ prepareMManager();
+ ProtoIndexRouter router = new
ProtoIndexRouter(IndexManager.getInstance().getIndexDirectory());
+ try {
+ router.removeIndexFromRouter(new PartialPath(index_sub), NO_INDEX);
+ Assert.fail();
+ } catch (MetadataException e) {
+ Assert.assertEquals("NO_INDEX hasn't been created on
root.wind1.azq01.speed", e.getMessage());
+ }
+ Assert.assertFalse(getIndexDirFile(index_sub, NO_INDEX).exists());
+ try {
+ router.removeIndexFromRouter(new PartialPath(index_full), NO_INDEX);
+ Assert.fail();
+ } catch (MetadataException e) {
+ Assert.assertEquals("NO_INDEX hasn't been created on
root.wind2.*.direction", e.getMessage());
+ }
+ Assert.assertFalse(getIndexDirFile(index_full, NO_INDEX).exists());
+ router.addIndexIntoRouter(new PartialPath(index_sub), infoSub_ELB,
createFunc, true);
+ Assert.assertTrue(getIndexDirFile(index_sub, ELB_INDEX).exists());
+ router.addIndexIntoRouter(new PartialPath(index_full), infoFull_RTREE,
createFunc, true);
+ Assert.assertTrue(getIndexDirFile(index_full, RTREE_PAA).exists());
+ router.removeIndexFromRouter(new PartialPath(index_sub), ELB_INDEX);
+ Assert.assertFalse(getIndexDirFile(index_sub, ELB_INDEX).exists());
+ try {
+ router.removeIndexFromRouter(new PartialPath(index_sub), ELB_INDEX);
+ Assert.assertFalse(getIndexDirFile(index_sub, ELB_INDEX).exists());
+ Assert.fail("should throw exception");
+ } catch (MetadataException e) {
+ Assert.assertEquals(
+ "ELB_INDEX hasn't been created on root.wind1.azq01.speed",
e.getMessage());
+ }
+ // System.out.println(router.toString());
+ }
+
+ @Test
+ public void testOperationWithoutStorageGroup() throws MetadataException,
IOException {
+ ProtoIndexRouter router = new
ProtoIndexRouter(IndexManager.getInstance().getIndexDirectory());
+ try {
+ router.addIndexIntoRouter(
+ new PartialPath(index_sub),
+ new IndexInfo(ELB_INDEX, 0, new HashMap<>()),
+ createFunc,
+ true);
+ Assert.fail();
+ } catch (MetadataException e) {
+ Assert.assertEquals("please set storage group before create index",
e.getMessage());
+ }
+ try {
+ router.removeIndexFromRouter(new PartialPath(index_sub), NO_INDEX);
+ Assert.fail();
+ } catch (MetadataException e) {
+ Assert.assertEquals("no storage group, remove nothing", e.getMessage());
+ }
+ }
}