Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Commit

Permalink
feat: add dag stat method (#297)
Browse files Browse the repository at this point in the history
Co-authored-by: Rohitha <rohitha.polamarasetty-intl@cylogic.com>
  • Loading branch information
PolamarasettyRohitha and Rohitha committed Jun 23, 2023
1 parent 7a377cf commit 45de4b3
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
83 changes: 83 additions & 0 deletions dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

files "github.com/ipfs/boxo/files"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-ipfs-api/options"
)

Expand Down Expand Up @@ -37,6 +38,46 @@ type DagImportOutput struct {
Stats *DagImportStats
}

type DagStat struct {
Cid cid.Cid `json:",omitempty"`
Size uint64 `json:",omitempty"`
NumBlocks int64 `json:",omitempty"`
}

type DagStatOutput struct {
redundantSize uint64 `json:"-"`
UniqueBlocks int `json:",omitempty"`
TotalSize uint64 `json:",omitempty"`
SharedSize uint64 `json:",omitempty"`
Ratio float32 `json:",omitempty"`
DagStatsArray []*DagStat `json:"DagStats,omitempty"`
}

func (s *DagStat) UnmarshalJSON(data []byte) error {
/*
We can't rely on cid.Cid.UnmarshalJSON since it uses the {"/": "..."}
format. To make the output consistent and follow the Kubo API patterns
we use the Cid.Parse method
*/

type Alias DagStat
aux := struct {
Cid string `json:"Cid"`
*Alias
}{
Alias: (*Alias)(s),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
Cid, err := cid.Parse(aux.Cid)
if err != nil {
return err
}
s.Cid = Cid
return nil
}

func (s *Shell) DagGet(ref string, out interface{}) error {
return s.Request("dag/get", ref).Exec(context.Background(), out)
}
Expand Down Expand Up @@ -151,3 +192,45 @@ func dagToFilesReader(data interface{}) (*files.MultiFileReader, error) {

return fileReader, nil
}

// DagStat gets stats for dag with default options
func (s *Shell) DagStat(data string) (DagStatOutput, error) {
return s.DagStatWithOpts(data)
}

// DagStatWithOpts gets stats for dag
func (s *Shell) DagStatWithOpts(data string, opts ...options.DagStatOption) (DagStatOutput, error) {
var out DagStatOutput
cfg, err := options.DagStatOptions(opts...)
if err != nil {
return out, err
}

resp, err := s.
Request("dag/stat", data).
Option("progress", cfg.Progress).
Send(context.Background())

if err != nil {
return out, err
}

defer resp.Close()

if resp.Error != nil {
return out, resp.Error
}

dec := json.NewDecoder(resp.Output)
for {
var v DagStatOutput
if err := dec.Decode(&v); err == io.EOF {
break
} else if err != nil {
return out, err
}
out = v
}

return out, nil
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module github.com/ipfs/go-ipfs-api
require (
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927
github.com/ipfs/boxo v0.8.0
github.com/ipfs/go-cid v0.4.0
github.com/libp2p/go-libp2p v0.26.3
github.com/mitchellh/go-homedir v1.1.0
github.com/multiformats/go-multiaddr v0.8.0
Expand All @@ -16,7 +17,6 @@ require (
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/ipfs/go-cid v0.4.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
Expand Down
33 changes: 33 additions & 0 deletions options/dag_stat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package options

// DagStatSettings is a set of Dag stat options.
type DagStatSettings struct {
Progress bool
}

// DagStatOption is a single Dag option.
type DagStatOption func(opts *DagStatSettings) error

// DagStatOptions applies the given option to a DagStatSettings instance.
func DagStatOptions(opts ...DagStatOption) (*DagStatSettings, error) {
options := &DagStatSettings{
Progress: false,
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}

return options, nil
}

// Progress is an option for Dag.Stat which returns progressive data while reading through the DAG
func (dagOpts) Progress(progress bool) DagStatOption {
return func(opts *DagStatSettings) error {
opts.Progress = progress
return nil
}
}
30 changes: 30 additions & 0 deletions shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,3 +630,33 @@ func TestSwarmPeeringAdd(t *testing.T) {
_, err := s.SwarmPeeringAdd(context.Background(), addr)
is.Nil(err)
}

func TestDagStat(t *testing.T) {
is := is.New(t)
s := NewShell(shellUrl)

result, err := s.DagStat("QmUwp4xYq4pt1xavfCnpJ2aoVETf83AsvK3W8KvUGtyzFB")
is.Nil(err)
is.Equal(result.TotalSize, 3383728)

is.Equal(result.DagStatsArray[0].Cid.String(), "QmUwp4xYq4pt1xavfCnpJ2aoVETf83AsvK3W8KvUGtyzFB")
is.Equal(result.UniqueBlocks, 15)
is.Equal(result.redundantSize, 0)
is.Equal(result.SharedSize, 0)
is.Equal(result.Ratio, 1)
}

func TestDagStatWithOpts(t *testing.T) {
is := is.New(t)
s := NewShell(shellUrl)

result, err := s.DagStatWithOpts("QmUwp4xYq4pt1xavfCnpJ2aoVETf83AsvK3W8KvUGtyzFB", options.Dag.Progress(true))
is.Nil(err)
is.Equal(result.TotalSize, 3383728)

is.Equal(result.DagStatsArray[0].Cid.String(), "QmUwp4xYq4pt1xavfCnpJ2aoVETf83AsvK3W8KvUGtyzFB")
is.Equal(result.UniqueBlocks, 15)
is.Equal(result.redundantSize, 0)
is.Equal(result.SharedSize, 0)
is.Equal(result.Ratio, 1)
}

0 comments on commit 45de4b3

Please sign in to comment.