[#930] Build the names a JDBC backend gives its own trees once, from the id it was created with - #1007
Open
vharseko wants to merge 1 commit into
Open
Conversation
…wn trees once, from the id it was created with The escaped backend id, the catalog TreeName and the base DN of this backend's own compressed schema pair were built again on every call - per tree of every read-write open, per clear, and per stamped table of a clear's leftover scan. They are held in one object now, built at the first call that needs one: applyConfigurationChange() replaces config whole, while the tables of a storage stand under the id they were created with, and backend-id is read-only in the configuration framework precisely because it cannot move under a live backend. Built lazily and not in the constructor: a storage is constructed by callers that go on to name no tree of it at all. The base DNs isOwnTree() compares against are normalized once per leftover scan rather than once per table - DN.toNormalizedUrlSafeString() memoizes nothing, and it was the larger half of that loop's string work.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #930.
What it changes
The three names a JDBC backend builds out of its backend id — the escaped id, the
TreeNameof its catalog (#888) and the base DN of its own compressed schema pair (#881/#873) — were built again on every call: per tree of every read-write open (enrolInCatalog(), about 25 for a stock suffix), twice perisEnrolledTree(), per clear (catalogTables(),removeStorageFiles()), and per stamped table of a clear's leftover scan (isOwnTree()). They are now built once, in one object, at the first call that needs one.Held together in one holder rather than in three fields so the three can never come from two different ids.
Why once is correct, and not only cheaper.
applyConfigurationChange()replacesconfigwhole, while the tables of a storage — the catalog table among them — stand under the id they were created with. A name read again from a configuration that has moved would leave the storage naming a catalog nothing has ever written, and its own tables attributed to nobody by the clear's report. The configuration framework holdsbackend-idread-only ("The backend ID may not be altered after the backend is created in the server",BackendConfiguration.xml), so nothing renames a live backend through it — which is what makes reading the id once correct in the first place. It is the same reasonpoolConnectionStringand the standing read bound are read once and not re-read (#878, #885).Lazily and not in the constructor. A storage is constructed by callers that go on to name no tree of it at all —
JDBCStatementBoundTestCaseasks the bounds of statements of a storage whose configuration carries no backend id whatsoever, and a construction reading the id would fail there where today nothing reads it.The performance half is the smaller half.
String.replace(CharSequence,CharSequence)returnsthiswhen the target is absent, so an ordinary id allocated nothing in the escape to begin with; what is saved per call is theTreeNameand its string. Every one of those call sites is already paying a round trip to the database — an enrolment writes a row, and each table of the leftover scan costs areadStoredComment()query. So this is hygiene, as the issue says in its own Severity section, not a hot path.Also, in the same method
isOwnTree()calledDN.toNormalizedUrlSafeString()on every base DN for every table of the leftover scan, and that method memoizes nothing — it walks the DN and normalizes every RDN into a freshStringBuilder. It was by a good margin the larger half of that loop's string work. The normalized set is now built once per scan and handed in.base-dn, unlikebackend-id, is not read-only, so it is not pinned to a field — only hoisted out of the per-table loop. Behaviour is unchanged.Tests
New
CatalogNameTestCase(no database needed) pins that the catalog keeps the backend id the storage was built with. Written first; before the fix it failed withRan locally:
CatalogNameTestCase,CatalogConnectionTestCase,StampConnectionTestCase,JDBCStatementBoundTestCase— 63 tests, 0 failures;PgSqlTestCase(-Pprecommit verify -Dapi.version=1.44) — 79 tests, 0 failures, 0 skipped, so the container did start. It covers the clear and the leftover scan, including the assertion that a table of a base DN this backend serves is reported as its own.