From e768fc89ea7ab84a3906631630994a0fad1f5b2a Mon Sep 17 00:00:00 2001 From: Seebs Date: Fri, 23 Jul 2021 12:26:45 -0500 Subject: [PATCH] stop using pointers to time.Time We're reading timestamps as []int64, instead of allocating a time.Time for each timestamp, just use the same logic to determine whether to use the int64 timestamp that we would have used to decide whether to allocate it. We still have to check the whole run, though, because we're providing a large list of 0s instead of "no timestamps", for Reasons. --- api.go | 12 +++++------- field.go | 15 +++++++-------- index.go | 11 ----------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/api.go b/api.go index 7f22a52ed..0353b0f42 100644 --- a/api.go +++ b/api.go @@ -1607,14 +1607,12 @@ func (api *API) ImportWithTx(ctx context.Context, qcx *Qcx, req *ImportRequest, return errors.Wrap(err, "validating shard ownership") } - // Convert timestamps to time.Time. - timestamps := make([]*time.Time, len(req.Timestamps)) - for i, ts := range req.Timestamps { - if ts == 0 { - continue + var timestamps []int64 + for _, v := range req.Timestamps { + if v != 0 { + timestamps = req.Timestamps + break } - t := time.Unix(0, ts).UTC() - timestamps[i] = &t } // Import columnIDs into existence field. diff --git a/field.go b/field.go index 0bb88d6ce..839999aaf 100644 --- a/field.go +++ b/field.go @@ -1437,7 +1437,7 @@ func (f *Field) Range(qcx *Qcx, name string, op pql.Token, predicate int64) (*Ro } // Import bulk imports data. -func (f *Field) Import(qcx *Qcx, rowIDs, columnIDs []uint64, timestamps []*time.Time, opts ...ImportOption) (err0 error) { +func (f *Field) Import(qcx *Qcx, rowIDs, columnIDs []uint64, timestamps []int64, opts ...ImportOption) (err0 error) { // Set up import options. options := &ImportOptions{} @@ -1450,7 +1450,7 @@ func (f *Field) Import(qcx *Qcx, rowIDs, columnIDs []uint64, timestamps []*time. // Determine quantum if timestamps are set. q := f.TimeQuantum() - if hasTime(timestamps) { + if len(timestamps) > 0 { if q == "" { return errors.New("time quantum not set in field") } else if options.Clear { @@ -1470,16 +1470,15 @@ func (f *Field) Import(qcx *Qcx, rowIDs, columnIDs []uint64, timestamps []*time. return errors.New("bool field imports only support values 0 and 1") } - var timestamp *time.Time - if len(timestamps) > i { - timestamp = timestamps[i] - } + hasTime := len(timestamps) > i && timestamps[i] != 0 var standard []string - if timestamp == nil { + if !hasTime { standard = []string{viewStandard} } else { - standard = viewsByTime(viewStandard, *timestamp, q) + // Yes, we mean `0, ts`; ts is an int64 in UnixNano units, + // time.Unix takes seconds-and-nanoseconds. + standard = viewsByTime(viewStandard, time.Unix(0, timestamps[i]).UTC(), q) if !f.options.NoStandardView { // In order to match the logic of `SetBit()`, we want bits // with timestamps to write to both time and standard views. diff --git a/index.go b/index.go index b7204007f..370a328fb 100644 --- a/index.go +++ b/index.go @@ -22,7 +22,6 @@ import ( "sort" "strconv" "sync" - "time" "github.com/molecula/featurebase/v2/disco" "github.com/molecula/featurebase/v2/roaring" @@ -841,16 +840,6 @@ type IndexOptions struct { TrackExistence bool `json:"trackExistence"` } -// hasTime returns true if a contains a non-nil time. -func hasTime(a []*time.Time) bool { - for _, t := range a { - if t != nil { - return true - } - } - return false -} - type importKey struct { View string Shard uint64