Searching is trivial:
-* there is no actual searching, just a streaming through all the
- database file sequentially
-* if some root is specified, then the program will output only its
- hierarchy path, exiting after it is finished
+* searching is performed on each record streamed from the database
+* if -root is specified, then search will stop after that hierarchy part
+ is over
+* by default all elements are printed, unless you provide a single
+ argument that becomes "*X*" pattern matched on case-lowered path
+ elements
Updating algorithm is following:
$ glocate -db /tmp/glocate.db -tree
[beauty tree-like list of files with sizes and mtimes]
- $ glocate -db /tmp/glocate.db some/sub/path
- [just a part of the whole hierarchy]
+ $ glocate -db /tmp/glocate.db -root music
+ [just a music hierarchy path]
-and update it carefully:
+ $ glocate -db /tmp/glocate.db -root music blasphemy | grep "/$"
+ music/Blasphemy-2001-Gods_Of_War_+_Blood_Upon_The_Altar/
+ music/Cryptopsy-1994-Blasphemy_Made_Flesh/
+ music/Infernal_Blasphemy-2005-Unleashed/
+ music/Ravenous-Assembled_In_Blasphemy/
+ music/Sect_Of_Execration-2002-Baptized_Through_Blasphemy/
+ music/Spectral_Blasphemy-2012-Blasphmemial_Catastrophic/
+
+and update it carefully, providing the strip prefix to -update:
$ zfs snap big@snap2
- $ zfs diff -FH big@snap2 | glocate -db /tmp/glocate.db -strip /big/ -update
+ $ zfs diff -FH big@snap2 | glocate -db /tmp/glocate.db -update /big/
glocate is copylefted free software: see the file COPYING for copying
conditions.
"flag"
"log"
"os"
+ "path"
"strings"
"syscall"
)
func main() {
dbPath := flag.String("db", "glocate.db", "Path to database")
doIndex := flag.Bool("index", false, "Perform indexing")
- doUpdate := flag.Bool("update", false, "Feed zfs-diff and update the database")
- strip := flag.String("strip", "", "Strip prefix from zfs-diff's paths")
+ doUpdate := flag.String("update", "", "Update database")
showMachine := flag.Bool("machine", false, "Show machine friendly")
showTree := flag.Bool("tree", false, "Show human-friendly tree")
dryRun := flag.Bool("n", false, "Dry run, do not overwrite database")
+ rootPath := flag.String("root", "", "Search only that part of tree")
flag.Parse()
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
return
}
- if *doUpdate {
- tmp := updateWithDiff(*dbPath, *strip)
+ if *doUpdate != "" {
+ tmp := updateWithDiff(*dbPath, *doUpdate)
tmp.Close()
if !*dryRun {
dbCommit(*dbPath, tmp)
}()
var root []string
+ if *rootPath != "" {
+ root = strings.Split("./"+*rootPath, "/")
+ }
+
+ var pat string
if len(flag.Args()) > 0 {
- root = strings.Split("./"+flag.Arg(0), "/")
+ pat = "*" + flag.Arg(0) + "*"
}
rootMet := false
+ var matched bool
+ var namePrev []string
+ var i int
for ent := range entsReader {
if hasPrefix(ent.name, root) {
- entsPrinter <- ent
rootMet = true
+ if pat == "" {
+ entsPrinter <- ent
+ continue
+ }
+ for i = 0; i < len(ent.name); i++ {
+ if i == len(namePrev) || ent.name[i] != namePrev[i] {
+ break
+ }
+ }
+ for ; i < len(ent.name); i++ {
+ matched, err = path.Match(pat,
+ strings.ToLower(strings.TrimSuffix(ent.name[i], "/")))
+ if err != nil {
+ log.Fatalln(err)
+ }
+ }
+ if matched {
+ entsPrinter <- ent
+ }
+ namePrev = ent.name
} else if rootMet {
break
}