Skip to content

Commit 89f9d32

Browse files
committed
Delay allocation of inner collection in collectors until it is really needed
1 parent e75c7a7 commit 89f9d32

File tree

1 file changed

+47
-11
lines changed

1 file changed

+47
-11
lines changed

src/commonMain/kotlin/io/github/optimumcode/json/schema/OutputCollector.kt

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,25 @@ public sealed class OutputCollector<T> private constructor(
9595
private val parent: DelegateOutputCollector? = null,
9696
transformer: OutputErrorTransformer<Nothing> = NO_TRANSFORMATION,
9797
) : OutputCollector<Nothing>(parent, transformer) {
98-
private val reportedErrors = mutableListOf<ValidationError>()
98+
private lateinit var reportedErrors: MutableList<ValidationError>
99+
100+
private fun addError(error: ValidationError) {
101+
if (!::reportedErrors.isInitialized) {
102+
reportedErrors = ArrayList(1)
103+
}
104+
reportedErrors.add(error)
105+
}
106+
107+
private fun addErrors(errors: MutableList<ValidationError>) {
108+
if (::reportedErrors.isInitialized) {
109+
reportedErrors.addAll(errors)
110+
} else {
111+
reportedErrors = errors
112+
}
113+
}
99114

100115
override fun onError(error: ValidationError) {
101-
transformError(error)?.also(reportedErrors::add)
116+
transformError(error)?.also { addError(it) }
102117
}
103118

104119
override val output: Nothing
@@ -118,10 +133,10 @@ public sealed class OutputCollector<T> private constructor(
118133
}
119134

120135
override fun reportErrors() {
121-
if (reportedErrors.isEmpty()) {
136+
if (!::reportedErrors.isInitialized) {
122137
return
123138
}
124-
parent?.also { it.reportedErrors.addAll(reportedErrors) }
139+
parent?.also { it.addErrors(reportedErrors) }
125140
?: reportedErrors.forEach(errorCollector::onError)
126141
}
127142

@@ -175,25 +190,43 @@ public sealed class OutputCollector<T> private constructor(
175190
private val parent: Basic? = null,
176191
transformer: OutputErrorTransformer<ValidationOutput.Basic> = NO_TRANSFORMATION,
177192
) : OutputCollector<ValidationOutput.Basic>(parent, transformer) {
178-
private val errors = mutableListOf<BasicError>()
193+
private lateinit var errors: MutableSet<BasicError>
194+
195+
private fun addError(error: BasicError) {
196+
if (!::errors.isInitialized) {
197+
errors = linkedSetOf()
198+
}
199+
errors.add(error)
200+
}
201+
202+
private fun addErrors(errors: MutableSet<BasicError>) {
203+
if (::errors.isInitialized) {
204+
this.errors.addAll(errors)
205+
} else {
206+
this.errors = errors
207+
}
208+
}
179209

180210
override fun onError(error: ValidationError) {
181211
val err = transformError(error) ?: return
182-
errors +=
212+
addError(
183213
BasicError(
184214
keywordLocation = err.schemaPath,
185215
instanceLocation = err.objectPath,
186216
absoluteKeywordLocation = err.absoluteLocation,
187217
error = err.message,
188-
)
218+
),
219+
)
189220
}
190221

191222
override val output: ValidationOutput.Basic
192-
get() =
193-
ValidationOutput.Basic(
223+
get() {
224+
val errors = if (::errors.isInitialized) errors else emptySet()
225+
return ValidationOutput.Basic(
194226
valid = errors.isEmpty(),
195-
errors = errors.toSet(),
227+
errors = errors,
196228
)
229+
}
197230

198231
override fun updateLocation(path: JsonPointer): OutputCollector<ValidationOutput.Basic> = childCollector()
199232

@@ -210,7 +243,10 @@ public sealed class OutputCollector<T> private constructor(
210243
override fun childCollector(): OutputCollector<ValidationOutput.Basic> = Basic(this)
211244

212245
override fun reportErrors() {
213-
parent?.errors?.addAll(errors)
246+
if (!::errors.isInitialized) {
247+
return
248+
}
249+
parent?.addErrors(errors)
214250
}
215251
}
216252

0 commit comments

Comments
 (0)