-
Notifications
You must be signed in to change notification settings - Fork 111
/
rowplanner.go
86 lines (73 loc) · 2.32 KB
/
rowplanner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package blob
import (
"gocloud.dev/blob"
)
// objectWithPlan has details on download plan for the remote object
// the plan has following details
// - full download or partial download
// - in case of partial download
// - strategy of download (head or tail)
// - size of data to download
type objectWithPlan struct {
obj *blob.ListObject
full bool
extractOption *extractOption
}
type extractOption struct {
limitInBytes uint64
strategy ExtractPolicyStrategy
}
// rowPlanner is an interface that creates download plan of a cloud object
type rowPlanner interface {
// planFile creates download plan of a object
planFile(item *blob.ListObject) *objectWithPlan
// done returns true when download limit is breached
done() bool
}
// plannerWithGlobalLimits implements rowPlanner interface
// the limitInBytes is a combined limit on all files
type plannerWithGlobalLimits struct {
cumsizeInBytes uint64
strategy ExtractPolicyStrategy
limitInBytes uint64
full bool
}
func (r *plannerWithGlobalLimits) planFile(item *blob.ListObject) *objectWithPlan {
obj := &objectWithPlan{obj: item}
obj.full = true
if uint64(item.Size)+r.cumsizeInBytes > r.limitInBytes {
obj.full = false
obj.extractOption = &extractOption{limitInBytes: r.limitInBytes - r.cumsizeInBytes, strategy: r.strategy}
r.full = true
}
r.cumsizeInBytes += uint64(item.Size)
return obj
}
func (r *plannerWithGlobalLimits) done() bool {
return r.full
}
// plannerWithPerFileLimits implements rowPlanner interface
// limitInBytes is on individual file
type plannerWithPerFileLimits struct {
strategy ExtractPolicyStrategy
limitInBytes uint64
}
func (r *plannerWithPerFileLimits) planFile(item *blob.ListObject) *objectWithPlan {
return &objectWithPlan{
obj: item,
full: uint64(item.Size) < r.limitInBytes, // if requested more data than size of file
extractOption: &extractOption{limitInBytes: r.limitInBytes, strategy: r.strategy},
}
}
func (r *plannerWithPerFileLimits) done() bool {
return false
}
// plannerWithoutLimits implements rowPlanner interface
// there are no limits
type plannerWithoutLimits struct{}
func (r *plannerWithoutLimits) planFile(item *blob.ListObject) *objectWithPlan {
return &objectWithPlan{obj: item, full: true}
}
func (r *plannerWithoutLimits) done() bool {
return false
}