Repository navigation
Conversation
Message buffers (Statement input/output, RequestMessage, RowSet) now use MessageBuffer, a std::vector<std::byte> whose start is aligned to MESSAGE_BUFFER_ALIGNMENT (16 bytes) through an aligned allocator, instead of relying on the global allocator's alignment. RowSet rows are now spaced by getRowStride(), the message length rounded up to that alignment, so every row starts aligned (previously rows after the first could be misaligned). getAlignedLength() is not used because it requires a Firebird 4.0+ client.
This branch has not been deployed
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.
Addresses item 4 of #74 (feedback: "Probably should be getAlignedLength. But not only that, and not only there, buffer start should be aligned as well.").
Problem
RowSetplaced rowsgetMessageLength()bytes apart, so every row after the first could start misaligned for its fields.Statementinput/output,RequestMessage,RowSet) was a plainstd::vector<std::byte>, so its start alignment depended entirely on the global allocator.Changes
MessageBuffer.h:fbcpp::MessageBufferis astd::vector<std::byte>with an aligned allocator (impl::AlignedAllocator, which usesoperator newwithstd::align_val_t).MESSAGE_BUFFER_ALIGNMENT(16 bytes), which covers any field of a Firebird message.Statement:inMessageandoutMessageareMessageBuffer, and so are the return types ofgetInputMessage()andgetOutputMessage().RequestMessageandimpl::ParameterSetter: useMessageBufferfor the message.RowSet:MessageBuffer.getRowStride(), which is the message length rounded up toMESSAGE_BUFFER_ALIGNMENT.getRawRow()still returnsgetMessageLength()bytes, andgetRawBuffer()now holdsgetCount() * getRowStride()bytes.Notes for review
getAlignedLength():IMessageMetadata::getAlignedLength()andgetAlignment()only exist from interface version 4 (Firebird 4.0 clients), and Blobs cannot be created with a Firebird 3 client library #71 showed that Firebird 3 client libraries still matter. Rounding up to the fixed 16-byte alignment is always at least as strict, costs at most 15 bytes per row, and works with any client. If you'd rather usegetAlignedLength()when the client supports it, I can change it.getInputMessage(),getOutputMessage()andRowSet::getRawBuffer()change fromstd::vector<std::byte>toMessageBuffer. Code that usesauto&,.data(),.size()or iterators compiles unchanged. Code that namesstd::vector<std::byte>&explicitly needs to change it tofbcpp::MessageBuffer&.Tests
RowSetSuite/rowsAreAligneduses a result set whose message length isn't a multiple of 16. It checks that:RowSetrow starts aligned;RowSetsize checks now usegetRowStride().Full suite: 349 test cases pass (Windows, MSVC, Firebird 5.0.3 server).