]> Cypherpunks repositories - gostls13.git/commitdiff
path/filepath: optimize isReservedName
authorJoe Tsai <joetsai@digital-static.net>
Thu, 22 Sep 2022 23:54:19 +0000 (16:54 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 23 Sep 2022 04:34:52 +0000 (04:34 +0000)
A linear search through a list of 22 strings takes ~80ns.
A quick check for 3-4 byte strings reduces this check to 2ns
for a vast majority of inputs.
In the event of a name match, the new logic is either just
as fast (for "CON") or 10x faster (for "LPT9").

Change-Id: I412fa73beebd7c81dc95f9ed12c35ca1d5d6baf0
Reviewed-on: https://go-review.googlesource.com/c/go/+/433175
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/path/filepath/path_windows.go

index b4d8ac33010e753bf158f3c7f550995e52c7e5e1..80998decc6ea5b2b0da7e47fbf37ad404f0d0213 100644 (file)
@@ -13,24 +13,24 @@ func isSlash(c uint8) bool {
        return c == '\\' || c == '/'
 }
 
-// reservedNames lists reserved Windows names. Search for PRN in
-// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
-// for details.
-var reservedNames = []string{
-       "CON", "PRN", "AUX", "NUL",
-       "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
-       "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
-}
-
 // isReservedName returns true, if path is Windows reserved name.
 // See reservedNames for the full list.
 func isReservedName(path string) bool {
-       if len(path) == 0 {
-               return false
+       toUpper := func(c byte) byte {
+               if 'a' <= c && c <= 'z' {
+                       return c - ('a' - 'A')
+               }
+               return c
        }
-       for _, reserved := range reservedNames {
-               if strings.EqualFold(path, reserved) {
-                       return true
+
+       // For details, search for PRN in
+       // https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
+       if 3 <= len(path) && len(path) <= 4 {
+               switch string([]byte{toUpper(path[0]), toUpper(path[1]), toUpper(path[2])}) {
+               case "CON", "PRN", "AUX", "NUL":
+                       return len(path) == 3
+               case "COM", "LPT":
+                       return len(path) == 4 && '1' <= path[3] && path[3] <= '9'
                }
        }
        return false