Skip to content

volume/mounts: pre-compile regular expressions#42673

Merged
AkihiroSuda merged 5 commits intomoby:masterfrom
thaJeztah:regex_optimisation
Aug 19, 2021
Merged

volume/mounts: pre-compile regular expressions#42673
AkihiroSuda merged 5 commits intomoby:masterfrom
thaJeztah:regex_optimisation

Conversation

@thaJeztah
Copy link
Copy Markdown
Member

follow-up to #42520
closes #42667

Compile the regular expression, instead of 'ad-hoc'. For this to work, I moved
the splitting was moved out of parseMountRaw() into ParseMountRaw(), and the
former was renamed to parseMount(). This function still receives the 'raw' string,
as it's used to include the "raw" spec for inclusion in error messages.

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

@thaJeztah thaJeztah added status/2-code-review kind/refactor PR's that refactor, or clean-up code labels Jul 26, 2021
@thaJeztah
Copy link
Copy Markdown
Member Author

Opening as draft; only the last four commits are new

Compile the regular expression, instead of 'ad-hoc'. For this to work, I moved
the splitting was moved out of parseMountRaw() into ParseMountRaw(), and the
former was renamed to parseMount(). This function still receives the 'raw' string,
as it's used to include the "raw" spec for inclusion in error messages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It has the windowsParser/lcowParser as receiver, so no need to repeat
that it's for Windows.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This way, there's no need to pass down the regular expression, and the
validation is "just another" validator (which we already pass).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah thaJeztah force-pushed the regex_optimisation branch from 4913fd2 to 71b0e47 Compare July 27, 2021 07:58
This utility was just a shallow wrapper around executing the regular
expression, and in some cases, we didn't even use the error it returned,
so better to inline the code instead of abstracting it away.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah thaJeztah marked this pull request as ready for review July 27, 2021 09:29
@thaJeztah thaJeztah requested a review from tianon July 27, 2021 09:29
@thaJeztah
Copy link
Copy Markdown
Member Author

@tianon ptal (probably easiest to review commits individually)

@tianon
Copy link
Copy Markdown
Member

tianon commented Jul 29, 2021

I'm a little confused about still having all the strings around ("This function still receives the 'raw' string, as it's used to include the "raw" spec for inclusion in error messages.") -- if it's just used for error messages, regexp.Regexp has a String method that claims it returns the original expression back again, and that seems like it'd be enough?

@thaJeztah
Copy link
Copy Markdown
Member Author

@tianon had to read back what I wrote there, but that's about this function:

func (p *windowsParser) parseMount(arr []string, raw, volumeDriver string, destRegex *regexp.Regexp, convertTargetToBackslash bool, additionalValidators ...mountValidator) (*MountPoint, error) {

It receives both

  • the arr []string (volume-spec split into its components)
  • the raw string (volume-spec before it was split)

Last one is used because for some errors, it uses the original (pre-split) volume-spec to generate an error;

return nil, errInvalidSpec(raw)

And (of course) I thought: that's easy, I just remove the raw argument, and generate the error in ParseMountRaw() (the exported function);

m, err := p.parseMount(arr, raw, volumeDriver, mountDestinationRegexp, true, windowsSpecificValidators)
if err != nil {
    return nil, errInvalidSpec(raw)
}

But then found that

  • there's various errors it generates; errInvalidSpec, errInvalidMode, fmt.Errorf("%v: %v", errInvalidSpec(raw), err)
  • for the above, I was in doubt wheter or not wrapping errInvalidMode into a errInvalidSpec would be ok (perhaps it is)
  • for the errInvalidSpec errors, there is no error message to wrap (perhaps it could return a ErrInvalidMode (invalid volume specification), which we then format.

@thaJeztah
Copy link
Copy Markdown
Member Author

@tianon perhaps something this? d2eb3cd

@tianon
Copy link
Copy Markdown
Member

tianon commented Jul 29, 2021

Ah, I guess I was hoping there'd be a cleaner way to avoid keeping all the string variables too (like rxDestination) so we wouldn't accidentally use one of them instead of using the MustCompile'd versions, but I see now that they're mostly reused for multiple underlying expressions, so that's not super realistic. 😞

So I guess I'm more neutral on whether #42667 is worth solving by itself, but I think doing MustCompile in the package instead of in a function is probably better (since the error will be noticed sooner), and it looks like you've done other cleanups here too that look useful IMO.

@thaJeztah
Copy link
Copy Markdown
Member Author

Yeah, doing it once is probably still a good thing to do https://twitter.com/kolyshkin/status/1419025281780654081?s=20, that is, if it's ok to allocate a couple of kilobytes (saw @kolyshkin tweet about this recently 😂)

Screenshot 2021-07-29 at 22 57 23

@thaJeztah
Copy link
Copy Markdown
Member Author

@tianon were there things left to address, or all good? 🤗

@AkihiroSuda AkihiroSuda merged commit 8360de9 into moby:master Aug 19, 2021
@thaJeztah thaJeztah deleted the regex_optimisation branch August 19, 2021 11:56
@thaJeztah thaJeztah added this to the 21.xx milestone Oct 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/refactor PR's that refactor, or clean-up code status/2-code-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"const rx" variables in "volume/mounts" should probably use "regexp.MustCompile"

3 participants