carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package dbdoor
2
3import (
4 "errors"
5 "fmt"
6 "sync"
7)
8
9const HandleHeader = "X-Carlos-DB-Handle"
10
11type dbHandleState struct {
12 listMu sync.Mutex
13 mu sync.Mutex
14 plan []LTXFile
15 pinned bool
16 files map[string]LTXFile
17}
18
19func (c *Client) rememberFiles(level int, list ListResponse) ([]LTXFile, error) {
20 c.handles.mu.Lock()
21 defer c.handles.mu.Unlock()
22 if list.Protocol != 0 && list.Protocol != 2 {
23 return nil, errors.New("dbdoor: unsupported listing protocol")
24 }
25 if c.handles.pinned && list.Protocol != 2 {
26 return nil, errors.New("dbdoor: pinned listing protocol disappeared")
27 }
28 if list.Plan && list.Protocol != 2 {
29 return nil, errors.New("dbdoor: invalid pinned listing")
30 }
31 if list.Protocol == 0 {
32 return list.Files, nil
33 }
34 files := make(map[string]LTXFile, len(c.handles.files)+len(list.Files))
35 for k, v := range c.handles.files {
36 files[k] = v
37 }
38 seen := map[string]bool{}
39 out := make([]LTXFile, 0, len(list.Files))
40 for _, f := range list.Files {
41 k := GetTail(f.Level, f.MinTXID, f.MaxTXID)
42 if (!list.Plan && f.Level != level) || f.Level < 0 || f.Level > MaxLevel || f.MinTXID == 0 || f.MaxTXID < f.MinTXID || f.Handle == "" || f.Size < 0 || seen[k] {
43 return nil, errors.New("dbdoor: invalid pinned listing")
44 }
45 seen[k] = true
46 if old, ok := files[k]; ok {
47 if old.Size != f.Size {
48 return nil, errors.New("dbdoor: pinned file size changed; retry the database pull")
49 }
50 f = old // Preserve first handle and its metadata through retries/resumes.
51 }
52 files[k] = f
53 out = append(out, f)
54 }
55 if list.Plan {
56 if c.handles.plan == nil {
57 c.handles.plan = out
58 }
59 out = filesAtLevel(c.handles.plan, level)
60 }
61 c.handles.files = files
62 c.handles.pinned = true
63 return out, nil
64}
65
66func (c *Client) fileHandle(level int, lo, hi uint64) (string, error) {
67 c.handles.mu.Lock()
68 defer c.handles.mu.Unlock()
69 if !c.handles.pinned {
70 return "", nil
71 }
72 if f, ok := c.handles.files[GetTail(level, lo, hi)]; ok {
73 return f.Handle, nil
74 }
75 return "", fmt.Errorf("dbdoor: coordinate has no pinned handle: %d %s", level, Span(lo, hi))
76}
77
78func filesAtLevel(files []LTXFile, level int) []LTXFile {
79 out := make([]LTXFile, 0)
80 for _, f := range files {
81 if f.Level == level {
82 out = append(out, f)
83 }
84 }
85 return out
86}
87
88func (c *Client) planFiles(level int) ([]LTXFile, bool) {
89 c.handles.mu.Lock()
90 defer c.handles.mu.Unlock()
91 return filesAtLevel(c.handles.plan, level), c.handles.plan != nil
92}
93