Glob style pattern matcher for strings in Go.
Port of the https://github.com/hrakaroo/glob-library-java library to Go. All code (including tests) have been pulled over and converted. Everything compiles and all tests pass. Main benchmark for GlobEngine is is done. I may add a few more benchmark tests, but for now I'm going to call this done and cut a 1.0 release.
There are already several glob implementations (https://go.dev/src/path/filepath/match.go and https://pkg.go.dev/v.io/v23/glob among others), but most seem to be focused on file paths and treat slash as a hard separator.
The code coverage report was generated by running:
go test -coverprofile coverage.out
go tool cover -html=coverage.out -o coverage.html
Files
100.0% for engine.go
100.0% for compiler.go
Overall
100.0% of statements
Added some compile option tests and the library is now at 100% code test coverage.
To use it add
require github.com/hrakaroo/glob-library-go v1.0.0
in your go.mod file and then import the library in your code.
For my simple test this worked pretty well:
import glob "github.com/hrakaroo/glob-library-go"
func main() {
fmt.Println("hello")
m, err := glob.Compile("*foo*")
if err != nil {
panic(err)
}
fmt.Println(m.Matches("bogfoo"))
}
Added another benchmark to test the EqualToEngine execution speed against
strings.EqualFold.
Fixed the alloc issue with this version. I may want to add a couple more benchmark test, but this is pretty close to being ready for production.
First tagged version of this library.
The globBenchmark_test.go file has all of the benchmark tests. (Eventually I may split the
benchmarks out into their own files, but for now they are all in one file.)
Fair warning that I have not spent a significant amount of time on this so I may not have
construsted the benchmarks entirely in idiomatic Go, but they are running and do seem to be
giving useful results. All feedback or suggestions are appreciated.
All benchmarks were run with
> go test -bench . -benchmem
and all produced the following header
goos: darwin
goarch: amd64
pkg: github.com/hrakaroo/glob-library-go
cpu: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
For both the globWords and globLogLines benchmarks the glob pattern has been written specifically to prevent the Glob library from using an optimization.
BenchmarkGlobWords-4 43 28000556 ns/op 528 B/op 26 allocs/op
BenchmarkGreedyRegexWords-4 7 168131805 ns/op 14853 B/op 92 allocs/op
BenchmarkNonGreedyRegexWords-4 6 176012549 ns/op 9574 B/op 92 allocs/op
BenchmarkGlobLogLines-4 21 54344059 ns/op 528 B/op 26 allocs/op
BenchmarkGreedyRegexLogLines-4 4 297334020 ns/op 108286 B/op 95 allocs/op
BenchmarkNonGreedyRegexLogLines-4 4 304755895 ns/op 9618 B/op 92 allocs/op
For both words and logLines the glob library is considerably faster than both
the greedy and non greedy regex runs and have the fewest number of allocations.
For these benchmarks the 100th word (arbitrarily selected) in the word list was is used as the source
word to which all words are case insensitively compared. As there are no globs in the source word the
Glob library will optimize to use the EqualToEngine. This is then compared against a simple
strings.EqualFold which is a string case insensitive check.
BenchmarkGlogEqWords-4 70 15120213 ns/op 3 B/op 0 allocs/op
BenchmarkStringEqWords-4 99 11861602 ns/op 0 B/op 0 allocs/op
As expected, the Glob library with the EqualToEngine is almost 30% faster than a call to strings.EqualFold but
uses a bit more memory.