reimplement ProjectElement internals to efficiently store document child elements

This commit is contained in:
Martin Lippert
2025-05-15 13:49:58 +02:00
parent 607f072238
commit 3ae66ce9ce
3 changed files with 169 additions and 9 deletions

View File

@@ -11,6 +11,7 @@
package org.springframework.ide.vscode.commons.protocol.spring;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class AbstractSpringIndexElement implements SpringIndexElement {
@@ -24,7 +25,7 @@ public abstract class AbstractSpringIndexElement implements SpringIndexElement {
@Override
public List<SpringIndexElement> getChildren() {
return children;
return Collections.unmodifiableList(this.children);
}
public void addChild(SpringIndexElement child) {

View File

@@ -10,15 +10,22 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.protocol.spring;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ProjectElement extends AbstractSpringIndexElement {
public class ProjectElement implements SpringIndexElement {
private String projectName;
private Map<String, DocumentElement> documents;
private List<SpringIndexElement> otherElements;
public ProjectElement(String projectName) {
this.projectName = projectName;
this.documents = new ConcurrentHashMap<>();
this.otherElements = new ArrayList<>();
}
public String getProjectName() {
@@ -26,13 +33,36 @@ public class ProjectElement extends AbstractSpringIndexElement {
}
public void removeDocument(String docURI) {
List<SpringIndexElement> children = this.getChildren();
this.documents.remove(docURI);
}
@Override
public List<SpringIndexElement> getChildren() {
List<SpringIndexElement> result = new ArrayList<>();
result.addAll(documents.values());
result.addAll(otherElements);
for (Iterator<SpringIndexElement> iterator = children.iterator(); iterator.hasNext();) {
SpringIndexElement springIndexElement = (SpringIndexElement) iterator.next();
if (springIndexElement instanceof DocumentElement doc && doc.getDocURI().equals(docURI)) {
iterator.remove();
}
return result;
}
@Override
public void addChild(SpringIndexElement child) {
if (child instanceof DocumentElement document) {
documents.put(document.getDocURI(), document);
}
else {
otherElements.add(child);
}
}
@Override
public void removeChild(SpringIndexElement doc) {
if (doc instanceof DocumentElement document) {
documents.remove(document.getDocURI());
}
else {
otherElements.remove(doc);
}
}

View File

@@ -0,0 +1,129 @@
/*******************************************************************************
* Copyright (c) 2025 Broadcom
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Broadcom - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.protocol.spring;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.junit.jupiter.api.Test;
class ProjectElementTest {
@Test
void testAddDocumentChildren() {
ProjectElement project = new ProjectElement("projectName");
List<SpringIndexElement> children = project.getChildren();
assertEquals(0, children.size());
DocumentElement doc1 = new DocumentElement("docUri1");
DocumentElement doc2 = new DocumentElement("docUri2");
project.addChild(doc1);
project.addChild(doc2);
children = project.getChildren();
assertEquals(2, children.size());
assertTrue(children.contains(doc1));
assertTrue(children.contains(doc2));
}
@Test
void testAddNonDocumentChildren() {
ProjectElement project = new ProjectElement("projectName");
var child1 = new AbstractSpringIndexElement() {};
var child2 = new AbstractSpringIndexElement() {};
project.addChild(child1);
project.addChild(child2);
List<SpringIndexElement> children = project.getChildren();
assertEquals(2, children.size());
assertTrue(children.contains(child1));
assertTrue(children.contains(child2));
}
@Test
void testMixedProjectChildren() {
ProjectElement project = new ProjectElement("projectName");
var doc1 = new DocumentElement("docUri1");
var doc2 = new DocumentElement("docUri2");
project.addChild(doc1);
project.addChild(doc2);
var child1 = new AbstractSpringIndexElement() {};
var child2 = new AbstractSpringIndexElement() {};
project.addChild(child1);
project.addChild(child2);
List<SpringIndexElement> children = project.getChildren();
assertEquals(4, children.size());
assertTrue(children.contains(child1));
assertTrue(children.contains(child2));
assertTrue(children.contains(doc1));
assertTrue(children.contains(doc2));
}
@Test
void testRemoveProjectChildren() {
ProjectElement project = new ProjectElement("projectName");
var doc1 = new DocumentElement("docUri1");
var doc2 = new DocumentElement("docUri2");
project.addChild(doc1);
project.addChild(doc2);
var child1 = new AbstractSpringIndexElement() {};
var child2 = new AbstractSpringIndexElement() {};
project.addChild(child1);
project.addChild(child2);
project.removeDocument("docUri1");
List<SpringIndexElement> children = project.getChildren();
assertEquals(3, children.size());
assertTrue(children.contains(child1));
assertTrue(children.contains(child2));
assertFalse(children.contains(doc1));
assertTrue(children.contains(doc2));
project.removeDocument("docDoesNotExist");
children = project.getChildren();
assertEquals(3, children.size());
assertTrue(children.contains(child1));
assertTrue(children.contains(child2));
assertFalse(children.contains(doc1));
assertTrue(children.contains(doc2));
project.removeChild(child2);
children = project.getChildren();
assertEquals(2, children.size());
assertTrue(children.contains(child1));
assertFalse(children.contains(child2));
assertFalse(children.contains(doc1));
assertTrue(children.contains(doc2));
}
}