summaryrefslogtreecommitdiff
path: root/cmd/btrfs-rec
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-30 23:07:13 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-01-30 23:07:13 -0700
commit9eef4dd91c36b60a2d5a68141f1d0c07e25be129 (patch)
tree4754b06e54d7e888e636472007fc1bc87aa72d72 /cmd/btrfs-rec
parent0134f07a4b97a455557277b2c89e0ee5ad6b2e62 (diff)
parent50a8b3eac39caccedb3ec34c150ba37e40cc2da5 (diff)
Merge branch 'lukeshu/fast-json'
Diffstat (limited to 'cmd/btrfs-rec')
-rw-r--r--cmd/btrfs-rec/inspect_rebuildmappings.go2
-rw-r--r--cmd/btrfs-rec/inspect_rebuildnodes.go2
-rw-r--r--cmd/btrfs-rec/inspect_scandevices.go2
-rw-r--r--cmd/btrfs-rec/main.go5
-rw-r--r--cmd/btrfs-rec/util.go68
5 files changed, 13 insertions, 66 deletions
diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go
index e1f273c..51f0327 100644
--- a/cmd/btrfs-rec/inspect_rebuildmappings.go
+++ b/cmd/btrfs-rec/inspect_rebuildmappings.go
@@ -47,7 +47,7 @@ func init() {
}
dlog.Infof(ctx, "Writing reconstructed mappings to stdout...")
- if err := writeJSONFile(os.Stdout, fs.LV.Mappings(), lowmemjson.ReEncoder{
+ if err := writeJSONFile(os.Stdout, fs.LV.Mappings(), lowmemjson.ReEncoderConfig{
Indent: "\t",
ForceTrailingNewlines: true,
CompactIfUnder: 120, //nolint:gomnd // This is what looks nice.
diff --git a/cmd/btrfs-rec/inspect_rebuildnodes.go b/cmd/btrfs-rec/inspect_rebuildnodes.go
index d813f36..e8f9ada 100644
--- a/cmd/btrfs-rec/inspect_rebuildnodes.go
+++ b/cmd/btrfs-rec/inspect_rebuildnodes.go
@@ -57,7 +57,7 @@ func init() {
dlog.Errorf(ctx, "rebuild error: %v", rebuildErr)
}
dlog.Infof(ctx, "Writing re-built nodes to %s...", dst.Name())
- if err := writeJSONFile(dst, rebuilder.ListRoots(), lowmemjson.ReEncoder{
+ if err := writeJSONFile(dst, rebuilder.ListRoots(), lowmemjson.ReEncoderConfig{
Indent: "\t",
ForceTrailingNewlines: true,
}); err != nil {
diff --git a/cmd/btrfs-rec/inspect_scandevices.go b/cmd/btrfs-rec/inspect_scandevices.go
index ade9d74..3de35d0 100644
--- a/cmd/btrfs-rec/inspect_scandevices.go
+++ b/cmd/btrfs-rec/inspect_scandevices.go
@@ -31,7 +31,7 @@ func init() {
}
dlog.Info(ctx, "Writing scan results to stdout...")
- if err := writeJSONFile(os.Stdout, results, lowmemjson.ReEncoder{
+ if err := writeJSONFile(os.Stdout, results, lowmemjson.ReEncoderConfig{
Indent: "\t",
ForceTrailingNewlines: true,
CompactIfUnder: 16, //nolint:gomnd // This is what looks nice.
diff --git a/cmd/btrfs-rec/main.go b/cmd/btrfs-rec/main.go
index d9ab485..d4165bf 100644
--- a/cmd/btrfs-rec/main.go
+++ b/cmd/btrfs-rec/main.go
@@ -16,6 +16,7 @@ import (
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil"
+ "git.lukeshu.com/btrfs-progs-ng/lib/profile"
"git.lukeshu.com/btrfs-progs-ng/lib/textui"
)
@@ -61,6 +62,7 @@ func main() {
if err := argparser.MarkPersistentFlagFilename("mappings"); err != nil {
panic(err)
}
+ stopProfiling := profile.AddProfileFlags(argparser.PersistentFlags(), "profile.")
openFlag := os.O_RDONLY
@@ -113,6 +115,9 @@ func main() {
err = _err
}
}
+ defer func() {
+ maybeSetErr(stopProfiling())
+ }()
fs, err := btrfsutil.Open(ctx, openFlag, pvsFlag...)
if err != nil {
return err
diff --git a/cmd/btrfs-rec/util.go b/cmd/btrfs-rec/util.go
index 9a0d60c..3d751a6 100644
--- a/cmd/btrfs-rec/util.go
+++ b/cmd/btrfs-rec/util.go
@@ -9,77 +9,20 @@ import (
"context"
"io"
"os"
- "time"
"git.lukeshu.com/go/lowmemjson"
"github.com/datawire/dlib/dlog"
- "git.lukeshu.com/btrfs-progs-ng/lib/textui"
+ "git.lukeshu.com/btrfs-progs-ng/lib/streamio"
)
-type runeScanner struct {
- ctx context.Context //nolint:containedctx // For detecting shutdown from methods
- progress textui.Portion[int64]
- progressWriter *textui.Progress[textui.Portion[int64]]
- unreadCnt uint64
- reader *bufio.Reader
- closer io.Closer
-}
-
-func newRuneScanner(ctx context.Context, fh *os.File) (*runeScanner, error) {
- fi, err := fh.Stat()
- if err != nil {
- return nil, err
- }
- ret := &runeScanner{
- ctx: ctx,
- progress: textui.Portion[int64]{
- D: fi.Size(),
- },
- progressWriter: textui.NewProgress[textui.Portion[int64]](ctx, dlog.LogLevelInfo, textui.Tunable(1*time.Second)),
- reader: bufio.NewReader(fh),
- closer: fh,
- }
- return ret, nil
-}
-
-func (rs *runeScanner) ReadRune() (r rune, size int, err error) {
- if err := rs.ctx.Err(); err != nil {
- return 0, 0, err
- }
- r, size, err = rs.reader.ReadRune()
- if rs.unreadCnt > 0 {
- rs.unreadCnt--
- } else {
- rs.progress.N += int64(size)
- rs.progressWriter.Set(rs.progress)
- }
- return
-}
-
-func (rs *runeScanner) UnreadRune() error {
- if err := rs.ctx.Err(); err != nil {
- return err
- }
- if err := rs.reader.UnreadRune(); err != nil {
- return err
- }
- rs.unreadCnt++
- return nil
-}
-
-func (rs *runeScanner) Close() error {
- rs.progressWriter.Done()
- return rs.closer.Close()
-}
-
func readJSONFile[T any](ctx context.Context, filename string) (T, error) {
fh, err := os.Open(filename)
if err != nil {
var zero T
return zero, err
}
- buf, err := newRuneScanner(dlog.WithField(ctx, "btrfs.read-json-file", filename), fh)
+ buf, err := streamio.NewRuneScanner(dlog.WithField(ctx, "btrfs.read-json-file", filename), fh)
defer func() {
_ = buf.Close()
}()
@@ -88,20 +31,19 @@ func readJSONFile[T any](ctx context.Context, filename string) (T, error) {
return zero, err
}
var ret T
- if err := lowmemjson.DecodeThenEOF(buf, &ret); err != nil {
+ if err := lowmemjson.NewDecoder(buf).DecodeThenEOF(&ret); err != nil {
var zero T
return zero, err
}
return ret, nil
}
-func writeJSONFile(w io.Writer, obj any, cfg lowmemjson.ReEncoder) (err error) {
+func writeJSONFile(w io.Writer, obj any, cfg lowmemjson.ReEncoderConfig) (err error) {
buffer := bufio.NewWriter(w)
defer func() {
if _err := buffer.Flush(); err == nil && _err != nil {
err = _err
}
}()
- cfg.Out = buffer
- return lowmemjson.Encode(&cfg, obj)
+ return lowmemjson.NewEncoder(lowmemjson.NewReEncoder(buffer, cfg)).Encode(obj)
}