func main()

in cmd/main.go [19:150]


func main() {
	app := &cli.App{
		Commands: []*cli.Command{
			{
				Name:  "compile",
				Usage: "compile a list of terms into a quotient filter",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:    "output",
						Aliases: []string{"out", "o"},
						Value:   "qf.bin",
						Usage:   "name of the file to write the quotient filter to",
					},
					&cli.StringFlag{
						Name:    "input",
						Aliases: []string{"in", "i"},
						Usage:   "file to read from (default is stdin)",
					},
					&cli.BoolFlag{
						Name:    "bitpacked",
						Aliases: []string{"p"},
						Usage:   "whether to bitpack the output",
					},
				},
				Action: func(c *cli.Context) error {
					output := c.String("output")
					if _, err := os.Stat(output); !os.IsNotExist(err) {
						return fmt.Errorf("refusing to over-write existing file: %s", output)
					}
					if c.NArg() > 0 {
						return fmt.Errorf("unexpected command line arguments: %q", c.Args().Slice())
					}

					var reader io.Reader
					if c.IsSet("input") {
						f, err := os.Open(c.String("input"))
						if err != nil {
							return err
						}
						reader = f
						defer f.Close()
					} else {
						reader = os.Stdin
					}

					filter := qf.NewWithConfig(qf.Config{BitPacked: c.Bool("bitpacked")})
					rdr := bufio.NewReader(reader)
					start := time.Now()
					for {
						l, _, err := rdr.ReadLine()
						if err != nil {
							if err == io.EOF {
								break
							}
							return err
						}
						s := strings.TrimSpace(string(l))
						filter.InsertString(s)
					}
					log.Printf("built in memory quotient filter in %s", time.Since(start))
					o, e := os.Create(output)
					if e != nil {
						return fmt.Errorf("error opening %s: %s", output, e)
					}
					defer o.Close()
					if n, err := filter.WriteTo(o); err != nil {
						return fmt.Errorf("error writing quotient filter: %s", err)
					} else {
						log.Printf("wrote %d bytes to %s", n, output)
					}
					filter.DebugDump(false)
					return nil
				},
			},
			{
				Name:  "lookup",
				Usage: "lookup a string from a quotient filter",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:    "input",
						Aliases: []string{"in", "i"},
						Usage:   "file containing quotient filter",
					},
				},
				Action: func(c *cli.Context) error {
					filter, err := qf.OpenReadOnlyFromPath(c.String("i"))
					if err != nil {
						return fmt.Errorf("can't read input file", err)
					}
					test := strings.Join(c.Args().Slice(), " ")
					found, ext := filter.LookupString(test)
					fmt.Printf("lookup %q: %t", test, found)
					if filter.HasStorage() && found {
						fmt.Printf(" - value: %d", ext)
					}
					fmt.Printf("\n")
					return nil
				},
			},
			{
				Name:  "describe",
				Usage: "read the header from a quotient filter and describe it",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:    "input",
						Aliases: []string{"in", "i"},
						Usage:   "file containing quotient filter",
					},
				},
				Action: func(c *cli.Context) error {
					h, err := qf.ReadHeaderFromPath(c.String("i"))
					if err != nil {
						return fmt.Errorf("can't read input file", err)
					}
					fmt.Printf("Quotient filter version %d\n", h.Version)
					not := "not "
					if h.BitPacked {
						not = ""
					}
					fmt.Printf("%sbitpacked - %d entries, %d quotient bits, %d storage bits\n",
						not, h.Entries, h.QBits, h.StorageBits)
					return nil
				},
			},
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}
}