Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Introduce small buffer in redis parser #4076

Merged
merged 2 commits into from
Jan 7, 2025
Merged

chore: Introduce small buffer in redis parser #4076

merged 2 commits into from
Jan 7, 2025

Conversation

romange
Copy link
Collaborator

@romange romange commented Nov 6, 2024

This change is needed in order to eliminate cases where we return INPUT_PENDING but do not consume the whole string by rejecting several bytes.

This will simplify buffer management on the caller's size, so that if they pass a string that
does not result in complete parsed request, the whole string is consumed by the parser and the passed string can be
discarded.

@romange romange requested a review from kostasrim November 6, 2024 16:31
kostasrim
kostasrim previously approved these changes Nov 6, 2024
Copy link
Contributor

@kostasrim kostasrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

InitStart(str[0], res);
}
DCHECK(state_ != CMD_COMPLETE_S);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to check this. InitStart does update state_ if it's equal CMD_COMPLETE_S so it's fine.

src/facade/redis_parser.cc Outdated Show resolved Hide resolved
if (pos[-1] != '\r') {
return BAD_INT;

consumed = pos - s + 1;
Copy link
Contributor

@kostasrim kostasrim Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am blindly trusting you here. I haven;t checked the index calculations but the tests are failing and it's a sign that there is a mistake somewhere around here 😄

@kostasrim
Copy link
Contributor

Tests are failing :)

kostasrim
kostasrim previously approved these changes Nov 7, 2024
@romange romange force-pushed the Parser branch 9 times, most recently from dbf8419 to 6ce0516 Compare November 10, 2024 20:09
@romange romange force-pushed the Parser branch 4 times, most recently from e84c303 to b788c86 Compare November 29, 2024 09:03
@romange romange force-pushed the Parser branch 3 times, most recently from 63a3bf1 to f7fa90c Compare December 11, 2024 17:32
@kostasrim
Copy link
Contributor

@romange still not green

@romange
Copy link
Collaborator Author

romange commented Dec 12, 2024

And I still have not requested to review :)

@kostasrim
Copy link
Contributor

And I still have not requested to review :)

Uhhh I saw the notification and saw you asked 😄 nvm

@romange romange force-pushed the Parser branch 7 times, most recently from 002d26d to 992fbe8 Compare December 18, 2024 08:44
@romange romange force-pushed the Parser branch 4 times, most recently from c6bfd07 to 38de90f Compare January 6, 2025 13:34
@romange romange changed the title chore: parser cleanups chore: Introduce small buffer in redis parser Jan 6, 2025
@romange romange requested a review from BorysTheDev January 6, 2025 13:36
This is needed in order to eliminate cases where we return INPUT_PENDING but do not consume the whole string by rejecting just several bytes.
This should simplify buffer management for the caller, so that if they pass a string that
did not result in complete parsed request, at least the whole string is consumed and can be discarded.

Signed-off-by: Roman Gershman <[email protected]>
@@ -114,6 +114,7 @@ class RedisParser {

using Blob = std::vector<uint8_t>;
std::vector<Blob> buf_stash_;
char small_buf_[32];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use std::array? and use size instead of sizeof(small_buf_)

Comment on lines 371 to 381
DCHECK_LT(small_len_, 2); // must be because we never fill here with more than 2 bytes.
unsigned needed = 2 - small_len_;
unsigned consumed = min<unsigned>(needed, str.size());

for (unsigned i = 0; i < consumed; ++i) {
small_buf_[small_len_++] = str[i];
}

if (small_len_ < 2) {
return {INPUT_PENDING, consumed};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to ignore, it's just a small idea to make a switch case with fallthrough to avoid extra IF and DCHECK can be done in the default section

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i hate how this code looks like. and it handles only 2 chars :)
how do you suggest to do this?

Copy link
Contributor

@BorysTheDev BorysTheDev Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	if (str.size() == 1 && small_len_ == 0) {
	  small_buf_[small_len_++] = str[0]; // small_len_ == 1
	  return {INPUT_PENDING, consumed};
	} 
	
	auto str_p = str.data();
	switch (small_len) {
	 default: assert(false);
	 case 0: small_buf_[small_len_++] = *(str_p++); [[fallthrough]]
	 case 1: small_buf_[small_len_++] = *str_p;	// small_len == 2
	}

After I wrote it, it doesn't look so beautiful :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, not much better 🤷🏼

Comment on lines 459 to 461
DCHECK_EQ(bulk_len_, 0u);

if (bulk_len_ == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have DCHECK why do you need if

BorysTheDev
BorysTheDev previously approved these changes Jan 6, 2025
Signed-off-by: Roman Gershman <[email protected]>
@romange romange merged commit a4d243b into main Jan 7, 2025
9 checks passed
@romange romange deleted the Parser branch January 7, 2025 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants