Skip to content

Commit

Permalink
Merge branch 'master' into v2-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
guregu committed May 20, 2024
2 parents 95d7bd1 + 929601d commit 23cb3df
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 26 deletions.
12 changes: 12 additions & 0 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ var itemEncodeOnlyTests = []struct {
"Public": &types.AttributeValueMemberN{Value: ("555")},
},
},
{
name: "nil exported pointer embedded struct",
in: struct {
ID string
*ExportedEmbedded
}{
ID: "abc",
},
out: Item{
"ID": &types.AttributeValueMemberS{Value: "abc"},
},
},
}

func TestMarshal(t *testing.T) {
Expand Down
2 changes: 0 additions & 2 deletions encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ var typeCache sync.Map // unmarshalKey → *typedef
type typedef struct {
decoders map[unmarshalKey]decodeFunc
fields []structField
root reflect.Type
info *structInfo
}

func newTypedef(rt reflect.Type) (*typedef, error) {
def := &typedef{
decoders: make(map[unmarshalKey]decodeFunc),
// encoders: make(map[encodeKey]encodeFunc),
root: rt,
}
err := def.init(rt)
return def, err
Expand Down
29 changes: 18 additions & 11 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,11 @@ func (q *Query) SearchLimit(limit int) *Query {
}

// RequestLimit specifies the maximum amount of requests to make against DynamoDB's API.
// func (q *Query) RequestLimit(limit int) *Query {
// q.reqLimit = limit
// return q
// }
// A limit of zero or less means unlimited requests.
func (q *Query) RequestLimit(limit int) *Query {
q.reqLimit = limit
return q
}

// Order specifies the desired result order.
// Requires a range key (a.k.a. partition key) to be specified.
Expand Down Expand Up @@ -277,21 +278,24 @@ func (q *Query) Count(ctx context.Context) (int, error) {
}

var count int
var scanned int32
var reqs int
var res *dynamodb.QueryOutput
for {
req := q.queryInput()
req.Select = selectCount
input := q.queryInput()
input.Select = selectCount

err := q.table.db.retry(ctx, func() error {
var err error
res, err = q.table.db.client.Query(ctx, req)
res, err = q.table.db.client.Query(ctx, input)
if err != nil {
return err
}
if res.Count == 0 {
return errors.New("nil count")
}
reqs++

count += int(res.Count)
scanned += res.ScannedCount

return nil
})
if err != nil {
Expand All @@ -302,7 +306,10 @@ func (q *Query) Count(ctx context.Context) (int, error) {
}

q.startKey = res.LastEvaluatedKey
if res.LastEvaluatedKey == nil || q.searchLimit > 0 {
if res.LastEvaluatedKey == nil ||
(q.limit > 0 && count >= q.limit) ||
(q.searchLimit > 0 && scanned >= q.searchLimit) ||
(q.reqLimit > 0 && reqs >= q.reqLimit) {
break
}
}
Expand Down
5 changes: 4 additions & 1 deletion reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ func indirectPtrNoAlloc(rv reflect.Value) reflect.Value {
func dig(rv reflect.Value, index []int) reflect.Value {
rv = indirectNoAlloc(rv)
for i, idx := range index {
if !rv.IsValid() {
break
}
if i == len(index)-1 {
rv = indirectPtrNoAlloc(rv.Field(idx))
} else {
Expand Down Expand Up @@ -201,11 +204,11 @@ type encodeKey struct {

type structInfo struct {
root reflect.Type
parent *structInfo
fields map[string]*structField // by name
refs map[encodeKey][]*structField
types map[encodeKey]encodeFunc
zeros map[reflect.Type]func(reflect.Value) bool
parent *structInfo

seen map[encodeKey]struct{}
queue []encodeKey
Expand Down
24 changes: 12 additions & 12 deletions scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ func (s *Scan) SearchLimit(limit int) *Scan {
}

// RequestLimit specifies the maximum amount of requests to make against DynamoDB's API.
// func (s *Scan) RequestLimit(limit int) *Scan {
// s.reqLimit = limit
// return s
// }
// A limit of zero or less means unlimited requests.
func (s *Scan) RequestLimit(limit int) *Scan {
s.reqLimit = limit
return s
}

// ConsumedCapacity will measure the throughput capacity consumed by this operation and add it to cc.
func (s *Scan) ConsumedCapacity(cc *ConsumedCapacity) *Scan {
Expand Down Expand Up @@ -247,6 +248,7 @@ func (s *Scan) Count(ctx context.Context) (int, error) {
var scanned int32
input := s.scanInput()
input.Select = types.SelectCount
var reqs int
for {
var out *dynamodb.ScanOutput
err := s.table.db.retry(ctx, func() error {
Expand All @@ -255,8 +257,9 @@ func (s *Scan) Count(ctx context.Context) (int, error) {
return err
})
if err != nil {
return count, err
return 0, err
}
reqs++

count += int(out.Count)
scanned += out.ScannedCount
Expand All @@ -265,13 +268,10 @@ func (s *Scan) Count(ctx context.Context) (int, error) {
addConsumedCapacity(s.cc, out.ConsumedCapacity)
}

if s.limit > 0 && count >= s.limit {
break
}
if s.searchLimit > 0 && scanned >= s.searchLimit {
break
}
if out.LastEvaluatedKey == nil {
if out.LastEvaluatedKey == nil ||
(s.limit > 0 && count >= s.limit) ||
(s.searchLimit > 0 && scanned >= s.searchLimit) ||
(s.reqLimit > 0 && reqs >= s.reqLimit) {
break
}

Expand Down

0 comments on commit 23cb3df

Please sign in to comment.