Mercurial > hg > Members > shoshi > jungle > jungle-core
changeset 285:1a36841024f2
fix index update
and BenchMark create index
author | tatsuki |
---|---|
date | Fri, 30 Dec 2016 20:26:28 +0900 |
parents | 49a5391df988 |
children | 3705cc48f74b |
files | src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/CreateTreeMethod.java src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/JungleTreeCreater.java src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/index/CreateIndexBenchMark.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/Index.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexUpdater.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/Differencial/DifferencialTreeNodeChildren.java src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/InterfaceTraverser.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/IndexTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/JungleTreeCreaterTest.java |
diffstat | 10 files changed, 204 insertions(+), 105 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/CreateTreeMethod.java Fri Dec 30 07:18:54 2016 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -package jp.ac.u_ryukyu.ie.cr.benchMark; - -import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath; -import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor; -import jp.ac.u_ryukyu.ie.cr.jungle.util.Either; -import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error; -import junit.framework.Assert; - -import java.nio.ByteBuffer; - -/** - * Created by e115731 on 2016/12/28. - */ -public class CreateTreeMethod { - - public static JungleTreeEditor createTree(JungleTreeEditor editor, String key, String indexKey, int _maxHeight, NodePath path) { - JungleTreeEditor newEditor = createTree(editor, key, indexKey, 0, _maxHeight, path); - Either<Error,JungleTreeEditor> either = newEditor.success(); - if (either.isA()) - Assert.fail(); - return either.b(); - } - - private static JungleTreeEditor createTree(JungleTreeEditor editor, String key, String indexKey, int _curY, int _maxHeight, NodePath path) { - if (_curY == _maxHeight) { - return editor; - } - for (int i = 0; i < 3; i++) { - Either<Error, JungleTreeEditor> either = editor.addNewChildAt(path, i); - if (either.isA()) - Assert.fail(); - editor = either.b(); - String value = path.add(i).toString(); - either = editor.putAttribute(path.add(i), key, ByteBuffer.wrap(value.getBytes())); - if (either.isA()) - Assert.fail(); - editor = either.b(); - either = editor.putAttribute(path.add(i), indexKey, ByteBuffer.wrap(value.getBytes())); - if (either.isA()) - Assert.fail(); - editor = either.b(); - editor = createTree(editor, key, indexKey, _curY + 1, _maxHeight, path.add(i)); - } - return editor; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/JungleTreeCreater.java Fri Dec 30 20:26:28 2016 +0900 @@ -0,0 +1,72 @@ +package jp.ac.u_ryukyu.ie.cr.benchMark; + +import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath; +import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.util.Either; +import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error; +import junit.framework.Assert; + +import java.nio.ByteBuffer; + + +public class JungleTreeCreater { + + int maxDeps; + int maxNodeCount; + int nodeCount = 1;//今作ったノードのカウント、rootがあるから最初は1 + public JungleTreeCreater(int maxNodeCount) { + this.maxNodeCount = maxNodeCount; + this.maxDeps = getMaxDeps(maxNodeCount); + } + + public JungleTreeEditor createTree(JungleTreeEditor editor, String key, String indexKey, NodePath path) { + int deps = 1; + JungleTreeEditor newEditor = createTree(editor, key, indexKey, deps, path); + Either<Error, JungleTreeEditor> either = newEditor.success(); + if (either.isA()) + Assert.fail(); + return either.b(); + } + + private JungleTreeEditor createTree(JungleTreeEditor editor, String key, String indexKey, int deps, NodePath path) { + Either<Error, JungleTreeEditor> either; + for (int i = 0; i < 3; i++) { + if (nodeCount == maxNodeCount || maxDeps == deps) { + return editor; + } + either = editor.addNewChildAt(path, i); + if (either.isA()) + Assert.fail(); + editor = either.b(); + String value = path.add(i).toString(); + either = editor.putAttribute(path.add(i), key, ByteBuffer.wrap(value.getBytes())); + if (either.isA()) + Assert.fail(); + editor = either.b(); + either = editor.success(); + if (either.isA()) + Assert.fail(); + editor = either.b(); + nodeCount++; + } + for (int i = 0; i < 3; i++) { + editor = createTree(editor, key, indexKey, deps + 1, path.add(i)); + } + return editor; + } + + private int getMaxDeps(int maxNodeCount) { + int i = 1; + int count = 1; //深さを決めるために使う。 + int currentNodeCount = 1; + for (; count < maxNodeCount; i++) { + count = count + (currentNodeCount * 3); + currentNodeCount = currentNodeCount * 3; + } + return i; + } + + public int getDeps() { + return maxDeps; + } +}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/index/CreateIndexBenchMark.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/benchMark/index/CreateIndexBenchMark.java Fri Dec 30 20:26:28 2016 +0900 @@ -1,5 +1,6 @@ package jp.ac.u_ryukyu.ie.cr.benchMark.index; +import jp.ac.u_ryukyu.ie.cr.benchMark.JungleTreeCreater; import jp.ac.u_ryukyu.ie.cr.jungle.DefaultJungle; import jp.ac.u_ryukyu.ie.cr.jungle.Jungle; import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath; @@ -7,13 +8,6 @@ import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor; import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser; import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree; -import jp.ac.u_ryukyu.ie.cr.jungle.util.Either; -import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error; -import org.junit.Assert; - -import java.nio.ByteBuffer; - -import static jp.ac.u_ryukyu.ie.cr.benchMark.CreateTreeMethod.createTree; /** * Created by e115731 on 2016/12/30. @@ -23,26 +17,19 @@ String key = "key"; String indexKey = "indexKey"; Jungle jungle = new DefaultJungle(null, "hogehoge", new DefaultTraverser()); - JungleTree tree = jungle.createNewTree("Tree"); - JungleTreeEditor editor = tree.getJungleTreeEditor(); - NodePath path = new DefaultNodePath(); - System.out.println("start create Tree"); - createTree(editor, key, indexKey, 5, path); System.out.println("end create Tree"); + for (int i = 1; i <= 10; i++) { - NodePath editNodePath = new DefaultNodePath(); - editNodePath = editNodePath.add(0).add(0).add(0).add(0).add(0);//.add(0).add(0).add(0).add(0); Long t1 = System.currentTimeMillis(); - for (int j = 0; j < (100 * i); j++) { - editor = tree.getJungleTreeEditor(); - Either<Error, JungleTreeEditor> either = editor.putAttribute(editNodePath, "key", ByteBuffer.wrap("value".getBytes())); - Assert.assertFalse(either.isA()); - editor = either.b(); - either = editor.success(); - Assert.assertFalse(either.isA()); - } + JungleTree tree = jungle.createNewTree("Tree" + i); + JungleTreeEditor editor = tree.getJungleTreeEditor(); + NodePath path = new DefaultNodePath(); + int maxNodeCount = 1000 * i; + JungleTreeCreater creater = new JungleTreeCreater(maxNodeCount); + editor = creater.createTree(editor, key, indexKey, path); Long t2 = System.currentTimeMillis(); System.out.println("edit count = " + (i * 100) + " : time = " + (t2 - t1)); + System.gc(); //GCしないとクソみたいに重くなる } } }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/Index.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/Index.java Fri Dec 30 20:26:28 2016 +0900 @@ -30,7 +30,7 @@ if (!indexOp.isPresent()) { TreeMap<String, List<TreeNode>> index = new TreeMap<>(); List<TreeNode> nodeList = new List<>(); - nodeList = nodeList.addLast(node); + nodeList = nodeList.add(0,node); TreeMap<String, List<TreeNode>> newIndex = index.put(value, nodeList); newIndexList = newIndexList.put(key, newIndex); return new Index(newIndexList); @@ -42,11 +42,11 @@ List<TreeNode> newNodeList; if (nodeListOp.isPresent()) { - newNodeList = nodeListOp.get().addLast(node); + newNodeList = nodeListOp.get().add(0,node); } else { List<TreeNode> nodeList = new List<>(); - newNodeList = nodeList.addLast(node); + newNodeList = nodeList.add(0,node); } TreeMap<String, List<TreeNode>> newIndex = index.put(value, newNodeList); @@ -89,4 +89,29 @@ } return new Index(newIndexList); } + + //test用 + public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndexList(){ + return indexList; + } + + public boolean contain(TreeNode node) { + TreeMap<String, TreeMap<String, List<TreeNode>>> newIndexList = indexList; + Attributes attribute = node.getAttributes(); + Iterator<String> keys = attribute.getKeys(); + while(keys.hasNext()) { + String key = keys.next(); + String value = attribute.getString(key); + Optional<TreeMap<String, List<TreeNode>>> indexOp = newIndexList.get(key); + if (!indexOp.isPresent()) + return false; + TreeMap<String, List<TreeNode>> index = indexOp.get(); + Optional<List<TreeNode>> nodeListOp = index.get(value); + if (!nodeListOp.isPresent()) + return false; + List<TreeNode> nodeList = nodeListOp.get(); + return nodeList.length() > 0; + } + return false; + } }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexUpdater.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/index/IndexUpdater.java Fri Dec 30 20:26:28 2016 +0900 @@ -12,30 +12,33 @@ public class IndexUpdater { private final TreeNode root; + private Index newIndex; + private ParentIndex newParentIndex; + private ParentIndex oldTreeParentIndex; - public IndexUpdater(TreeNode root) { + public IndexUpdater(TreeNode root, Index index, ParentIndex parentIndex) { this.root = root; + this.newIndex = index; + this.newParentIndex = parentIndex; + this.oldTreeParentIndex = parentIndex; } - public Pair<Index, ParentIndex> update(List<TreeNode> editedNodeList, Index index, ParentIndex parentIndex) { - Index newIndex = index; - ParentIndex newParentIndex = parentIndex; - Pair<Index,ParentIndex> pair = delete(editedNodeList, parentIndex, newIndex, newParentIndex); - newIndex = pair.left(); - newParentIndex = pair.right(); - return put(root, newIndex, newParentIndex); + public Pair<Index, ParentIndex> update(List<TreeNode> editedNodeList) { + delete(editedNodeList); + put(root); + return new Pair<>(newIndex,newParentIndex); } - private Pair<Index,ParentIndex> put(TreeNode currentNode, Index newIndex, ParentIndex newParentIndex) { + private void put(TreeNode currentNode) { + Children children = currentNode.getChildren(); + if (newIndex.contain(currentNode)) + return ; for (TreeNode child : children) { - if (newParentIndex.contain(child)) - return new Pair<Index,ParentIndex>(newIndex,newParentIndex); newParentIndex = newParentIndex.set(currentNode, child); - Pair<Index,ParentIndex> pair = put(child, newIndex, newParentIndex); - newIndex = pair.left(); - newParentIndex = pair.right(); + put(child); } + Attributes attribute = currentNode.getAttributes(); Iterator<String> keys = attribute.getKeys(); while (keys.hasNext()) { @@ -43,13 +46,12 @@ String value = attribute.getString(key); newIndex = newIndex.set(key, value, currentNode); } - return new Pair<Index,ParentIndex>(newIndex,newParentIndex); } - private Pair<Index,ParentIndex> delete(List<TreeNode> editedNodeList, ParentIndex parentIndex, Index newIndex, ParentIndex newParentIndex) { + private void delete(List<TreeNode> editedNodeList) { for (TreeNode node : editedNodeList) { newParentIndex = newParentIndex.deleteAllChildren(node); - Optional<TreeNode> parentOp = parentIndex.get(node); + Optional<TreeNode> parentOp = oldTreeParentIndex.get(node); if (parentOp.isPresent()) newIndex = newIndex.delete(node); while (parentOp.isPresent()) { @@ -58,11 +60,10 @@ if (tmp.equals(newParentIndex)) break; newParentIndex = tmp; - parentOp = parentIndex.get(parent); + parentOp = oldTreeParentIndex.get(parent); newIndex = newIndex.delete(parent); } } - return new Pair<Index,ParentIndex>(newIndex,newParentIndex); } }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/manager/DefaultTransactionManager.java Fri Dec 30 20:26:28 2016 +0900 @@ -66,8 +66,7 @@ Index index = tip.getIndex(); ParentIndex parentIndex = tip.getParentIndex(); InterfaceTraverser traverser = new InterfaceTraverser(newRoot, index, parentIndex, true); - //System.out.println("start"); - traverser.updateIndex(editNodeList); + //traverser.updateIndex(editNodeList); //traverser.createIndex(); //System.out.println("end"); TreeContext newTreeContext = new DefaultTreeContext(newRoot, tip, list, uuid, _treeName, nextRevision, traverser);
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/Differencial/DifferencialTreeNodeChildren.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/transaction/node/Differencial/DifferencialTreeNodeChildren.java Fri Dec 30 20:26:28 2016 +0900 @@ -87,7 +87,7 @@ @Override public Either<Error, TreeNode> at(int _pos) { - if (!boundaryCheck(_pos + 1) || _pos > 0 ) { + if (!boundaryCheck(_pos + 1) || _pos < 0 ) { return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS); } TreeNode n = children.get(_pos);
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/InterfaceTraverser.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/traverser/InterfaceTraverser.java Fri Dec 30 20:26:28 2016 +0900 @@ -17,7 +17,6 @@ private TreeNode root; private Index index; private ParentIndex parentIndex; - private IndexUpdater indexUpdater; private boolean parentUpdateFlag; private boolean useIndex; @@ -30,7 +29,6 @@ this.index = index; this.parentIndex = parentIndex; this.useIndex = useIndex; - this.indexUpdater = new IndexUpdater(root); } public Index getIndex() { @@ -52,7 +50,8 @@ } public void updateIndex(List<TreeNode> editedNodeList) { - Pair<Index,ParentIndex> p = indexUpdater.update(editedNodeList, index, parentIndex); + IndexUpdater indexUpdater = new IndexUpdater(root,index,parentIndex); + Pair<Index,ParentIndex> p = indexUpdater.update(editedNodeList); index = p.left(); parentIndex = p.right(); }
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/IndexTest.java Fri Dec 30 07:18:54 2016 +0900 +++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/index/IndexTest.java Fri Dec 30 20:26:28 2016 +0900 @@ -3,6 +3,7 @@ import jp.ac.u_ryukyu.ie.cr.jungle.DefaultJungle; import jp.ac.u_ryukyu.ie.cr.jungle.Jungle; import jp.ac.u_ryukyu.ie.cr.jungle.core.Children; +import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap; import jp.ac.u_ryukyu.ie.cr.jungle.query.JungleNodeIterator; import jp.ac.u_ryukyu.ie.cr.jungle.store.index.Index; import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath; @@ -21,6 +22,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Optional; import static jp.ac.u_ryukyu.ie.cr.jungle.CreateTreeMethod.createTree; @@ -45,7 +47,7 @@ TreeNode node = iterator.next(); TreeNodeAttributes attribute = node.getAttributes(); Iterator<String> keys = attribute.getKeys(); - while (keys.hasNext()) { + while (keys.hasNext()) { //作った木にちゃんとIndexが張られているかを調べる String attributeKey = keys.next(); String value = attribute.getString(attributeKey); Iterator<TreeNode> indexNode = index.get(attributeKey, value); @@ -70,35 +72,56 @@ TreeNode newTreeRoot = tree.getRootNode(); Index newIndex = tree.getIndex(); iterator = new JungleNodeIterator(newTreeRoot); - while (iterator.hasNext()) { + while (iterator.hasNext()) { //木を編集した際に差分でIndexがアップデートされているかを調べる TreeNode node = iterator.next(); TreeNodeAttributes attribute = node.getAttributes(); Iterator<String> keys = attribute.getKeys(); while (keys.hasNext()) { String attributeKey = keys.next(); String value = attribute.getString(attributeKey); - System.out.println(value); - if (value.equals("<-1,1,1,2>")) - System.out.println(value); Iterator<TreeNode> indexNode = newIndex.get(attributeKey, value); Assert.assertTrue(indexNode.hasNext()); Assert.assertEquals(indexNode.next(),node); } + newIndex = newIndex.delete(node); } + + TreeMap<String, TreeMap<String, jp.ac.u_ryukyu.ie.cr.jungle.data.list.List<TreeNode>>> indexList = newIndex.getIndexList(); //差分で更新した際不要な値がIndexに残っていないかを調べる + Iterator<String> indexKeys = indexList.keys(); + while(indexKeys.hasNext()){ + String indexKeys2 = indexKeys.next(); + Optional<TreeMap<String, jp.ac.u_ryukyu.ie.cr.jungle.data.list.List<TreeNode>>> treeMapIndexOp = indexList.get(indexKeys2); + Assert.assertTrue(treeMapIndexOp.isPresent()); + TreeMap<String, jp.ac.u_ryukyu.ie.cr.jungle.data.list.List<TreeNode>> treeMapIndex = treeMapIndexOp.get(); + Iterator<String> treeMapIndexKeys = treeMapIndex.keys(); + while (treeMapIndexKeys.hasNext()) { + String treeMapIndexkey = treeMapIndexKeys.next(); + Optional<jp.ac.u_ryukyu.ie.cr.jungle.data.list.List<TreeNode>> nodeListOp = treeMapIndex.get(treeMapIndexkey); + Assert.assertTrue(nodeListOp.isPresent()); + jp.ac.u_ryukyu.ie.cr.jungle.data.list.List<TreeNode> nodeList = nodeListOp.get(); + Assert.assertEquals(nodeList.length(),0); + } + } + + //編集する際に新しい木に残らないノードがIndexに混ざってないかをしらべる List<TreeNode> deletedNodeList = new LinkedList<>(); deletedNodeList = getDeletedNodeList(deletedNodeList, oldTreeRoot, path); deletedNodeList = getDeletedNodeList(deletedNodeList, oldTreeRoot, path2); - + newIndex = tree.getIndex(); for (TreeNode deletedNode : deletedNodeList) { TreeNodeAttributes attribute = deletedNode.getAttributes(); Iterator<String> keys = attribute.getKeys(); while (keys.hasNext()) { String attributeKey = keys.next(); String value = attribute.getString(key); - Iterator<TreeNode> indexNode = newIndex.get(attributeKey, value); - Assert.assertTrue(indexNode.hasNext()); - Assert.assertNotEquals(indexNode.next(),deletedNode); + Iterator<TreeNode> newIndexNode = newIndex.get(attributeKey, value); + Iterator<TreeNode> oldIndexNode = index.get(attributeKey, value); + Assert.assertTrue(newIndexNode.hasNext()); + Assert.assertTrue(oldIndexNode.hasNext()); + Assert.assertNotEquals(newIndexNode.next(),oldIndexNode.next()); + Assert.assertFalse(newIndexNode.hasNext()); + Assert.assertFalse(oldIndexNode.hasNext()); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/jungle/tree/JungleTreeCreaterTest.java Fri Dec 30 20:26:28 2016 +0900 @@ -0,0 +1,39 @@ +package jp.ac.u_ryukyu.ie.cr.jungle.tree; + +import jp.ac.u_ryukyu.ie.cr.benchMark.JungleTreeCreater; +import jp.ac.u_ryukyu.ie.cr.jungle.DefaultJungle; +import jp.ac.u_ryukyu.ie.cr.jungle.Jungle; +import jp.ac.u_ryukyu.ie.cr.jungle.query.JungleNodeIterator; +import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath; +import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath; +import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser; +import org.junit.Assert; +import org.junit.Test; + + +public class JungleTreeCreaterTest { + @Test + public void JungleTreeCreate() { + String key = "key"; + String indexKey = "indexKey"; + Jungle jungle = new DefaultJungle(null, "hogehoge", new DefaultTraverser()); + for (int count = 1; count <= 10; count++) { + int maxNodeCount = count * 10; + JungleTree tree = jungle.createNewTree("Tree" + count); + JungleTreeEditor editor = tree.getJungleTreeEditor(); + NodePath path = new DefaultNodePath(); + JungleTreeCreater creater = new JungleTreeCreater(maxNodeCount); + editor = creater.createTree(editor, key, indexKey, path); + TreeNode root = tree.getRootNode(); + JungleNodeIterator iterator = new JungleNodeIterator(root); + int nodeCount = 0; + while (iterator.hasNext()) { + iterator.next(); + nodeCount++; + } + Assert.assertEquals(nodeCount, maxNodeCount); + } + } +}