Skip to content

Commit

Permalink
CLI: info: handle durations > 2**63 (#844)
Browse files Browse the repository at this point in the history
* CLI: info: handle durations > 2**63

* make a function

* correct comment
  • Loading branch information
james-rms authored Mar 7, 2023
1 parent fd3ecad commit 39545db
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions go/cli/mcap/cmd/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"
"io"
"math"
"os"
"sort"
"time"
Expand All @@ -19,9 +20,8 @@ var (
)

func decimalTime(t time.Time) string {
unix := t.UnixNano()
seconds := unix / 1e9
nanoseconds := unix % 1e9
seconds := t.Unix()
nanoseconds := t.Nanosecond()
return fmt.Sprintf("%d.%09d", seconds, nanoseconds)
}

Expand All @@ -35,6 +35,19 @@ func humanBytes(numBytes uint64) string {
return fmt.Sprintf("%.2f %s", displayedValue, prefixes[prefixIndex])
}

func getDurationNs(start uint64, end uint64) float64 {
// subtracts start from end, returning the result as a 64-bit float.
// float64 can represent the entire range of possible durations (-2**64, 2**64),
// albeit with some loss of precision.
diff := end - start
signMultiplier := 1.0
if start > end {
diff = start - end
signMultiplier = -1.0
}
return float64(diff) * signMultiplier
}

func printInfo(w io.Writer, info *mcap.Info) error {
buf := &bytes.Buffer{}
fmt.Fprintf(buf, "library: %s\n", info.Header.Library)
Expand All @@ -45,16 +58,23 @@ func printInfo(w io.Writer, info *mcap.Info) error {
fmt.Fprintf(buf, "messages: %d\n", info.Statistics.MessageCount)
start = info.Statistics.MessageStartTime
end = info.Statistics.MessageEndTime
durationNs := getDurationNs(start, end)
durationInSeconds = durationNs / 1e9
starttime := time.Unix(int64(start/1e9), int64(start%1e9))
endtime := time.Unix(int64(end/1e9), int64(end%1e9))
fmt.Fprintf(buf, "duration: %s\n", endtime.Sub(starttime))
durationInSeconds = endtime.Sub(starttime).Seconds()
if math.Abs(durationNs) > math.MaxInt64 {
// time.Duration is an int64 nanosecond count under the hood, but end and start can
// be further apart than that.
fmt.Fprintf(buf, "duration: %.3fs\n", durationInSeconds)
} else {
fmt.Fprintf(buf, "duration: %s\n", endtime.Sub(starttime))
}
if starttime.After(LongAgo) {
fmt.Fprintf(buf, "start: %s (%s)\n", starttime.Format(time.RFC3339Nano), decimalTime(starttime))
fmt.Fprintf(buf, "end: %s (%s)\n", endtime.Format(time.RFC3339Nano), decimalTime(endtime))
} else {
fmt.Fprintf(buf, "start: %.3f\n", float64(starttime.UnixNano())/1e9)
fmt.Fprintf(buf, "end: %.3f\n", float64(endtime.UnixNano())/1e9)
fmt.Fprintf(buf, "start: %s\n", decimalTime(starttime))
fmt.Fprintf(buf, "end: %s\n", decimalTime(endtime))
}
}
if len(info.ChunkIndexes) > 0 {
Expand Down

0 comments on commit 39545db

Please sign in to comment.