git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/mmdb/reader_mmap.go (about) 1 //go:build !appengine && !plan9 && !js && !wasip1 2 // +build !appengine,!plan9,!js,!wasip1 3 4 package mmdb 5 6 import ( 7 "os" 8 "runtime" 9 ) 10 11 // Open takes a string path to a MaxMind DB file and returns a Reader 12 // structure or an error. The database file is opened using a memory map 13 // on supported platforms. On platforms without memory map support, such 14 // as WebAssembly or Google App Engine, the database is loaded into memory. 15 // Use the Close method on the Reader object to return the resources to the system. 16 func Open(file string) (*Reader, error) { 17 mapFile, err := os.Open(file) 18 if err != nil { 19 _ = mapFile.Close() 20 return nil, err 21 } 22 23 stats, err := mapFile.Stat() 24 if err != nil { 25 _ = mapFile.Close() 26 return nil, err 27 } 28 29 fileSize := int(stats.Size()) 30 mmap, err := mmap(int(mapFile.Fd()), fileSize) 31 if err != nil { 32 _ = mapFile.Close() 33 return nil, err 34 } 35 36 if err := mapFile.Close(); err != nil { 37 //nolint:errcheck // we prefer to return the original error 38 munmap(mmap) 39 return nil, err 40 } 41 42 reader, err := FromBytes(mmap) 43 if err != nil { 44 //nolint:errcheck // we prefer to return the original error 45 munmap(mmap) 46 return nil, err 47 } 48 49 reader.hasMappedFile = true 50 runtime.SetFinalizer(reader, (*Reader).Close) 51 return reader, nil 52 } 53 54 // Close returns the resources used by the database to the system. 55 func (r *Reader) Close() error { 56 var err error 57 if r.hasMappedFile { 58 runtime.SetFinalizer(r, nil) 59 r.hasMappedFile = false 60 err = munmap(r.buffer) 61 } 62 r.buffer = nil 63 return err 64 }