Skip to content

Commit 4c18caf

Browse files
authored
Merge pull request #2865 from 1c-syntax/fix/memory-consumption
Снижение потребления памяти
2 parents 8ce6141 + 62fece8 commit 4c18caf

18 files changed

+682
-91
lines changed

build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ plugins {
2222
id("ru.vyarus.pom") version "2.2.2"
2323
id("com.gorylenko.gradle-git-properties") version "2.4.1"
2424
id("io.codearte.nexus-staging") version "0.30.0"
25+
id("me.champeau.jmh") version "0.6.6"
2526
}
2627

2728
repositories {
@@ -80,7 +81,7 @@ dependencies {
8081
exclude("org.antlr", "antlr-runtime")
8182
exclude("org.glassfish", "javax.json")
8283
}
83-
api("com.github.1c-syntax", "utils", "0.4.0")
84+
api("com.github.1c-syntax", "utils", "f1694d9c")
8485
api("com.github.1c-syntax", "mdclasses", "0.10.3")
8586
api("io.github.1c-syntax", "bsl-common-library", "0.3.0")
8687
api("io.github.1c-syntax", "supportconf", "0.1.1")
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* This file is a part of BSL Language Server.
3+
*
4+
* Copyright (c) 2018-2022
5+
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
6+
*
7+
* SPDX-License-Identifier: LGPL-3.0-or-later
8+
*
9+
* BSL Language Server is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* BSL Language Server is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with BSL Language Server.
21+
*/
22+
package com.github._1c_syntax.bsl.languageserver.context.symbol;
23+
24+
import com.github._1c_syntax.bsl.languageserver.context.symbol.variable.VariableKind;
25+
import com.github._1c_syntax.bsl.languageserver.utils.Ranges;
26+
import org.eclipse.lsp4j.Range;
27+
import org.openjdk.jmh.annotations.Benchmark;
28+
import org.openjdk.jmh.annotations.Fork;
29+
import org.openjdk.jmh.annotations.Level;
30+
import org.openjdk.jmh.annotations.Param;
31+
import org.openjdk.jmh.annotations.Scope;
32+
import org.openjdk.jmh.annotations.Setup;
33+
import org.openjdk.jmh.annotations.State;
34+
import org.openjdk.jmh.annotations.Warmup;
35+
import org.openjdk.jmh.infra.Blackhole;
36+
37+
import java.util.Optional;
38+
39+
@State(Scope.Benchmark)
40+
public class VariableSymbolCreate {
41+
42+
private Range range;
43+
44+
@Param({"false", "true"})
45+
boolean shortBased;
46+
47+
@Setup(Level.Trial)
48+
public void setup() {
49+
int line = shortBased ? 100 : 60_000;
50+
range = Ranges.create(line, 0, line, 1);
51+
}
52+
53+
@Benchmark
54+
@Fork(value = 2, warmups = 2)
55+
@Warmup(time = 5, iterations = 3)
56+
public void createVariableSymbols(Blackhole bh) {
57+
var test = VariableSymbol.builder()
58+
.name("test")
59+
.owner(null)
60+
.range(range)
61+
.variableNameRange(range)
62+
.export(true)
63+
.kind(VariableKind.MODULE)
64+
.description(Optional.empty())
65+
.scope(null).build();
66+
67+
bh.consume(test);
68+
}
69+
70+
}

src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/SymbolTreeComputer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public SymbolTree compute() {
6464
currentParent = placeSymbol(topLevelSymbols, currentParent, symbol);
6565
}
6666

67+
collapseChildrenCollection(moduleSymbol);
68+
6769
return new SymbolTree(moduleSymbol);
6870
}
6971

@@ -89,4 +91,12 @@ private static SourceDefinedSymbol placeSymbol(
8991
return placeSymbol(topLevelSymbols, maybeParent.get(), symbol);
9092
}
9193

94+
private static void collapseChildrenCollection(SourceDefinedSymbol symbol) {
95+
var children = symbol.getChildren();
96+
if (children instanceof ArrayList) {
97+
((ArrayList<SourceDefinedSymbol>) children).trimToSize();
98+
}
99+
100+
children.forEach(SymbolTreeComputer::collapseChildrenCollection);
101+
}
92102
}
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* This file is a part of BSL Language Server.
3+
*
4+
* Copyright (c) 2018-2022
5+
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
6+
*
7+
* SPDX-License-Identifier: LGPL-3.0-or-later
8+
*
9+
* BSL Language Server is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* BSL Language Server is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with BSL Language Server.
21+
*/
22+
package com.github._1c_syntax.bsl.languageserver.context.symbol;
23+
24+
import com.github._1c_syntax.bsl.languageserver.context.DocumentContext;
25+
import com.github._1c_syntax.bsl.languageserver.context.symbol.variable.VariableDescription;
26+
import com.github._1c_syntax.bsl.languageserver.context.symbol.variable.VariableKind;
27+
import lombok.Builder;
28+
import lombok.EqualsAndHashCode;
29+
import lombok.Getter;
30+
import lombok.Setter;
31+
import lombok.ToString;
32+
import lombok.Value;
33+
import lombok.experimental.Accessors;
34+
import lombok.experimental.NonFinal;
35+
import org.eclipse.lsp4j.Range;
36+
import org.eclipse.lsp4j.SymbolKind;
37+
38+
import java.util.Collections;
39+
import java.util.List;
40+
import java.util.Optional;
41+
42+
/**
43+
* Общая реализация символа переменной.
44+
*/
45+
@Value
46+
@NonFinal
47+
@Builder(builderClassName = "Builder")
48+
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
49+
@ToString(exclude = {"children", "parent"})
50+
public abstract class AbstractVariableSymbol implements VariableSymbol {
51+
52+
/**
53+
* Имя переменной.
54+
*/
55+
@EqualsAndHashCode.Include
56+
String name;
57+
58+
/**
59+
* Область доступности символа. Метод или модуль.
60+
*/
61+
SourceDefinedSymbol scope;
62+
63+
/**
64+
* Файл в котором располагается переменная.
65+
*/
66+
@EqualsAndHashCode.Include
67+
DocumentContext owner;
68+
69+
/**
70+
* Символ, внутри которого располагается данный символ.
71+
*/
72+
@Getter
73+
@Setter
74+
@NonFinal
75+
Optional<SourceDefinedSymbol> parent;
76+
77+
/**
78+
* Список "детей" символа - символов, которые располагаются внутри данного символа.
79+
*/
80+
@Getter
81+
List<SourceDefinedSymbol> children;
82+
83+
/**
84+
* Тип переменной.
85+
*/
86+
byte kind;
87+
88+
/**
89+
* Признак экспортной переменной.
90+
*/
91+
boolean export;
92+
93+
/**
94+
* Описание переменной.
95+
*/
96+
Optional<VariableDescription> description;
97+
98+
@Override
99+
public SymbolKind getSymbolKind() {
100+
return SymbolKind.Variable;
101+
}
102+
103+
@Override
104+
public VariableKind getKind() {
105+
return VariableKind.values()[kind];
106+
}
107+
108+
@Override
109+
@EqualsAndHashCode.Include
110+
public abstract Range getVariableNameRange();
111+
112+
@Override
113+
public void accept(SymbolTreeVisitor visitor) {
114+
visitor.visitVariable(this);
115+
}
116+
117+
@Override
118+
public Range getSelectionRange() {
119+
return getVariableNameRange();
120+
}
121+
122+
public static class Builder {
123+
124+
@Setter
125+
@Accessors(fluent = true, chain = true)
126+
private VariableKind kind;
127+
128+
@Setter
129+
@Accessors(fluent = true, chain = true)
130+
Optional<SourceDefinedSymbol> parent = Optional.empty();
131+
132+
@Setter
133+
@Accessors(fluent = true, chain = true)
134+
List<SourceDefinedSymbol> children = Collections.emptyList();
135+
136+
private int startLine;
137+
private int startCharacter;
138+
private int endLine;
139+
private int endCharacter;
140+
private int variableNameLine;
141+
private int variableNameStartCharacter;
142+
private int variableNameEndCharacter;
143+
144+
public Builder range(Range range) {
145+
var start = range.getStart();
146+
var end = range.getEnd();
147+
startLine = start.getLine();
148+
startCharacter = start.getCharacter();
149+
endLine = end.getLine();
150+
endCharacter = end.getCharacter();
151+
152+
return this;
153+
}
154+
155+
public Builder variableNameRange(Range range) {
156+
var start = range.getStart();
157+
var end = range.getEnd();
158+
variableNameLine = start.getLine();
159+
variableNameStartCharacter = start.getCharacter();
160+
variableNameEndCharacter = end.getCharacter();
161+
162+
return this;
163+
}
164+
165+
public VariableSymbol build() {
166+
167+
// Ленивое булево вычисление диапазона переменной
168+
var shortBased = startLine <= Short.MAX_VALUE
169+
&& endLine <= Short.MAX_VALUE
170+
&& startCharacter <= Short.MAX_VALUE
171+
&& endCharacter <= Short.MAX_VALUE
172+
&& variableNameLine <= Short.MAX_VALUE
173+
&& variableNameStartCharacter <= Short.MAX_VALUE
174+
&& variableNameEndCharacter <= Short.MAX_VALUE;
175+
176+
if (shortBased) {
177+
return new ShortBasedVariableSymbol(
178+
name,
179+
scope,
180+
owner,
181+
parent,
182+
children,
183+
(byte) kind.ordinal(),
184+
export,
185+
description,
186+
(short) startLine,
187+
(short) startCharacter,
188+
(short) endLine,
189+
(short) endCharacter,
190+
(short) variableNameLine,
191+
(short) variableNameStartCharacter,
192+
(short) variableNameEndCharacter
193+
);
194+
} else {
195+
return new IntBasedVariableSymbol(
196+
name,
197+
scope,
198+
owner,
199+
parent,
200+
children,
201+
(byte) kind.ordinal(),
202+
export,
203+
description,
204+
startLine,
205+
startCharacter,
206+
endLine,
207+
endCharacter,
208+
variableNameLine,
209+
variableNameStartCharacter,
210+
variableNameEndCharacter
211+
);
212+
}
213+
}
214+
}
215+
216+
}

0 commit comments

Comments
 (0)