[#1096] Copy a value into Persistit once rather than twice, and write the large values of PDBStorageTest through a small buffer pool - #1097
Open
vharseko wants to merge 1 commit into
Conversation
…han twice, and write the large values of PDBStorageTest through a small buffer pool bytesToValue() copied each value into a fresh array with toByteArray() before Persistit copied it again into the value buffer of the exchange. The bytes now go straight into the encoded bytes of the value, behind the header Persistit itself writes for an empty byte array. For the 63 MB put of PDBStorageTest that is one humongous array fewer live next to the source and the 64 MB value buffer. testCanAddLargeValues also reopens its storage with a 16 MB buffer pool rather than 20% of the heap (76 MB under -Xmx512m); the other methods keep the percentage, which the memory quota tests are about. testCanAddLargeValues alone, JDK 17, three runs per heap: master runs out of heap from 320m down, the bytesToValue() change alone from 256m down, both together first at 224m, on the allocation of the 63 MB source itself. testValuesReadBackAsWritten pins the encoding: an empty value, one past the offset of its array, a ByteStringBuilder and a 64 KB value which outgrows the encoded bytes read back as written.
vharseko
force-pushed
the
issues/1096-pdb-value-copy
branch
from
September 24, 2026 15:44
5031563 to
d0e7584
Compare
Member
Author
|
@maximthomas I rebased onto master (d0e7584) after #1066 made this PR conflict. The only conflict was in the imports of On this head |
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 #1096.
PDBStorageTest.testCanAddLargeValuesstill ran the 512 MB test JVM out of heap after #1072 -build-maven (ubuntu-latest, 17)of #1057, intoByteArray()ofPDBStorage.bytesToValue()on the 63 MB put. This takes both remaining options named under "Left out" of #1072.Why
On the way into Persistit the 63 MB value still had three humongous arrays live at once: the source, the
toByteArray()copy, and the 64 MB value buffer of the exchange - on top of the buffer pool of the test storage (76 MB, 20% of the heap) and the test server. Under-Xmx512ma G1 region is 1 MB, so each 63 MB array needs a free run of 64 regions, which humongous objects already in place can break up: whether it is there is up to the collector's timing.The change
Main -
PDBStorage.bytesToValue(). The bytes are copied once, straight into the encoded bytes of theValue: the header is what Persistit itself writes for an empty byte array (putByteArray(new byte[0])), thenensureFit(len),copyTo(getEncodedBytes(), header),setEncodedSize(header + len). The bytes stored are the same as before - Persistit encodes a byte array as the header followed by the bytes as they are (checked inValue.putByteArray1of the 3.1.2 in use) - and no private constant of Persistit is copied. Every put and update of a PDB backend saves one allocation of the size of its value.Test -
PDBStorageTest.testCanAddLargeValuesreopens its storage with a 16 MB buffer pool. The other methods keepdb-cache-percent: the memory quota tests (aStorageWhoseOpenFailedGivesBackWhatItTookand its neighbours) are about that branch.testValuesReadBackAsWritten(new) pins the encoding: an empty value, aByteStringpast the offset of its array, aByteStringBuilder, and a 64 KB patterned value which outgrows the encoded bytes the value had - so the bytes have to land in the arrayensureFit()put in place of the old one.Measured
testCanAddLargeValuesalone, JDK 17.0.20, three runs per cell:-XmxbytesToValue()onlyFour mutants of
bytesToValue()failtestValuesReadBackAsWritten: the bytes written over the header, nosetEncodedSize(), the size without the header, and the encoded bytes read beforeensureFit()(caught by the 64 KB value only:copyTo()truncates silently into the old array).The whole class under
-Xmx512m: 10/10 under JDK 17, 5/5 under JDK 26 on the first head (5031563).Rebased onto master after #1066 (1aa253d), which touched the imports of
PDBStorageTestas well: the only conflict wasResultCodeandByteStringBuilderadded on the same line, and both are kept. The change itself is unchanged (git range-diffdiffers only in that context). On this headPDBStorageTestpasses 28/28, the 13 cache size tests #1066 added included.Left out
The
-Xmx512mof the test fork in the rootpom.xmlstays as it is.bytesToKey()keeps its copy: keys are small, andKey.appendByteArray()escapes the bytes rather than taking them as they are.