Skip to content

Commit 3ae66ce

Browse files
committed
reimplement ProjectElement internals to efficiently store document child elements
1 parent 607f072 commit 3ae66ce

File tree

3 files changed

+169
-9
lines changed

3 files changed

+169
-9
lines changed

headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/AbstractSpringIndexElement.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package org.springframework.ide.vscode.commons.protocol.spring;
1212

1313
import java.util.ArrayList;
14+
import java.util.Collections;
1415
import java.util.List;
1516

1617
public abstract class AbstractSpringIndexElement implements SpringIndexElement {
@@ -24,7 +25,7 @@ public AbstractSpringIndexElement() {
2425

2526
@Override
2627
public List<SpringIndexElement> getChildren() {
27-
return children;
28+
return Collections.unmodifiableList(this.children);
2829
}
2930

3031
public void addChild(SpringIndexElement child) {

headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/ProjectElement.java

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,59 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.commons.protocol.spring;
1212

13-
import java.util.Iterator;
13+
import java.util.ArrayList;
1414
import java.util.List;
15+
import java.util.Map;
16+
import java.util.concurrent.ConcurrentHashMap;
1517

16-
public class ProjectElement extends AbstractSpringIndexElement {
18+
public class ProjectElement implements SpringIndexElement {
1719

1820
private String projectName;
21+
22+
private Map<String, DocumentElement> documents;
23+
private List<SpringIndexElement> otherElements;
1924

2025
public ProjectElement(String projectName) {
2126
this.projectName = projectName;
27+
this.documents = new ConcurrentHashMap<>();
28+
this.otherElements = new ArrayList<>();
2229
}
2330

2431
public String getProjectName() {
2532
return projectName;
2633
}
2734

2835
public void removeDocument(String docURI) {
29-
List<SpringIndexElement> children = this.getChildren();
36+
this.documents.remove(docURI);
37+
}
38+
39+
@Override
40+
public List<SpringIndexElement> getChildren() {
41+
List<SpringIndexElement> result = new ArrayList<>();
42+
43+
result.addAll(documents.values());
44+
result.addAll(otherElements);
3045

31-
for (Iterator<SpringIndexElement> iterator = children.iterator(); iterator.hasNext();) {
32-
SpringIndexElement springIndexElement = (SpringIndexElement) iterator.next();
33-
if (springIndexElement instanceof DocumentElement doc && doc.getDocURI().equals(docURI)) {
34-
iterator.remove();
35-
}
46+
return result;
47+
}
48+
49+
@Override
50+
public void addChild(SpringIndexElement child) {
51+
if (child instanceof DocumentElement document) {
52+
documents.put(document.getDocURI(), document);
53+
}
54+
else {
55+
otherElements.add(child);
56+
}
57+
}
58+
59+
@Override
60+
public void removeChild(SpringIndexElement doc) {
61+
if (doc instanceof DocumentElement document) {
62+
documents.remove(document.getDocURI());
63+
}
64+
else {
65+
otherElements.remove(doc);
3666
}
3767
}
3868

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Broadcom
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Broadcom - initial API and implementation
10+
*******************************************************************************/
11+
package org.springframework.ide.vscode.commons.protocol.spring;
12+
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.junit.jupiter.api.Assertions.assertFalse;
15+
import static org.junit.jupiter.api.Assertions.assertTrue;
16+
17+
import java.util.List;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
class ProjectElementTest {
22+
23+
@Test
24+
void testAddDocumentChildren() {
25+
ProjectElement project = new ProjectElement("projectName");
26+
27+
List<SpringIndexElement> children = project.getChildren();
28+
assertEquals(0, children.size());
29+
30+
DocumentElement doc1 = new DocumentElement("docUri1");
31+
DocumentElement doc2 = new DocumentElement("docUri2");
32+
33+
project.addChild(doc1);
34+
project.addChild(doc2);
35+
36+
children = project.getChildren();
37+
assertEquals(2, children.size());
38+
39+
assertTrue(children.contains(doc1));
40+
assertTrue(children.contains(doc2));
41+
}
42+
43+
@Test
44+
void testAddNonDocumentChildren() {
45+
ProjectElement project = new ProjectElement("projectName");
46+
47+
var child1 = new AbstractSpringIndexElement() {};
48+
var child2 = new AbstractSpringIndexElement() {};
49+
50+
project.addChild(child1);
51+
project.addChild(child2);
52+
53+
List<SpringIndexElement> children = project.getChildren();
54+
assertEquals(2, children.size());
55+
56+
assertTrue(children.contains(child1));
57+
assertTrue(children.contains(child2));
58+
}
59+
60+
@Test
61+
void testMixedProjectChildren() {
62+
ProjectElement project = new ProjectElement("projectName");
63+
64+
var doc1 = new DocumentElement("docUri1");
65+
var doc2 = new DocumentElement("docUri2");
66+
67+
project.addChild(doc1);
68+
project.addChild(doc2);
69+
70+
var child1 = new AbstractSpringIndexElement() {};
71+
var child2 = new AbstractSpringIndexElement() {};
72+
73+
project.addChild(child1);
74+
project.addChild(child2);
75+
76+
List<SpringIndexElement> children = project.getChildren();
77+
assertEquals(4, children.size());
78+
79+
assertTrue(children.contains(child1));
80+
assertTrue(children.contains(child2));
81+
assertTrue(children.contains(doc1));
82+
assertTrue(children.contains(doc2));
83+
}
84+
85+
@Test
86+
void testRemoveProjectChildren() {
87+
ProjectElement project = new ProjectElement("projectName");
88+
89+
var doc1 = new DocumentElement("docUri1");
90+
var doc2 = new DocumentElement("docUri2");
91+
92+
project.addChild(doc1);
93+
project.addChild(doc2);
94+
95+
var child1 = new AbstractSpringIndexElement() {};
96+
var child2 = new AbstractSpringIndexElement() {};
97+
98+
project.addChild(child1);
99+
project.addChild(child2);
100+
101+
project.removeDocument("docUri1");
102+
List<SpringIndexElement> children = project.getChildren();
103+
assertEquals(3, children.size());
104+
105+
assertTrue(children.contains(child1));
106+
assertTrue(children.contains(child2));
107+
assertFalse(children.contains(doc1));
108+
assertTrue(children.contains(doc2));
109+
110+
project.removeDocument("docDoesNotExist");
111+
children = project.getChildren();
112+
assertEquals(3, children.size());
113+
114+
assertTrue(children.contains(child1));
115+
assertTrue(children.contains(child2));
116+
assertFalse(children.contains(doc1));
117+
assertTrue(children.contains(doc2));
118+
119+
project.removeChild(child2);
120+
children = project.getChildren();
121+
assertEquals(2, children.size());
122+
123+
assertTrue(children.contains(child1));
124+
assertFalse(children.contains(child2));
125+
assertFalse(children.contains(doc1));
126+
assertTrue(children.contains(doc2));
127+
}
128+
129+
}

0 commit comments

Comments
 (0)