feat(web): add .codepointLength field for SearchQuotientNode types 🚂#15440
feat(web): add .codepointLength field for SearchQuotientNode types 🚂#15440jahorton merged 4 commits intoepic/autocorrectfrom
Conversation
User Test ResultsTest specification and instructions User tests are not required Test Artifacts
|
4c06d81 to
53ed374
Compare
36f8441 to
cf6643d
Compare
db9f4ed to
92d0472
Compare
cf6643d to
da23429
Compare
Build-bot: skip build:web Skip-bot: skip
92d0472 to
cfe72f4
Compare
da23429 to
3149eab
Compare
|
|
||
| get codepointLength(): number { | ||
| if(this._codepointLength === undefined) { | ||
| this._codepointLength = this.parentNode.codepointLength + this.insertLength - this.leftDeleteLength; |
There was a problem hiding this comment.
Shouldn't we set this outside of get()?
There was a problem hiding this comment.
OK, so this gets a bit complicated because of the TS type system.
Note the .insertLength and .leftDeleteLength properties.
Those two properties cannot be set in the SearchQuotientSpur constructor and are thus unavailable for use in initializing the field during construction time. As a result, I opted to take a "lazy initialization" strategy - we'll calculate it once, when it's needed, and lock in the value at that time.
While it could be dynamically generated at runtime on each access, bypassing the need to set an instance field entirely, that'd make accesses an O(N) call each time on the length of the string, rather than O(1). (I'm aiming to optimize the number of KMWString calls, as the code involves lots of branches and loops, thus could suffer significant branch-prediction misses.)
There was a problem hiding this comment.
| this._codepointLength = this.parentNode.codepointLength + this.insertLength - this.leftDeleteLength; | |
| // caching result for performance | |
| // note that readonly abstract props cannot be accessed in constructor | |
| this._codepointLength = this.parentNode.codepointLength + this.insertLength - this.leftDeleteLength; |
But this does feel a little bit like working too hard for structural elegance (readonly abstract properties) and shooting yourself in the foot in the process because then you need this pattern. Another way of solving this could be by including the value or values as parameters to the SearchQuotientSpur constructor.
|
|
||
| return { | ||
| text: KMWString.substring(bestPrefix.text, 0, KMWString.length(bestPrefix.text) - bestLocalInput.sample.deleteLeft) + bestLocalInput.sample.insert, | ||
| text: KMWString.substring(bestPrefix.text, 0, (this.parentNode?.codepointLength ?? 0) - bestLocalInput.sample.deleteLeft) + bestLocalInput.sample.insert, |
There was a problem hiding this comment.
For maintainability of what bestExample() is calculating, can we we split this change to a const above? (to a descriptive variable) along with some comments how it's "best".
In order to move the implementation of
.splitoperations onto theSearchQuotientNodetypes, its instances will need a way to recursively find the correct split point..codepointLength, along with the helper.leftDeleteLengthand.insertLengthproperties, will provide a clear and clean way to do exactly that.Build-bot: skip build:web
Test-bot: skip