1package cache
2
3import (
4 "encoding/gob"
5
6 "github.com/MichaelMure/git-bug/bug"
7 "github.com/MichaelMure/git-bug/util/lamport"
8)
9
10// BugExcerpt hold a subset of the bug values to be able to sort and filter bugs
11// efficiently without having to read and compile each raw bugs.
12type BugExcerpt struct {
13 Id string
14
15 CreateLamportTime lamport.Time
16 EditLamportTime lamport.Time
17 CreateUnixTime int64
18 EditUnixTime int64
19
20 Status bug.Status
21 Author AuthorExcerpt
22 Labels []bug.Label
23
24 CreateMetadata map[string]string
25}
26
27type AuthorExcerpt struct {
28 Name string
29 Login string
30}
31
32func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt {
33 return &BugExcerpt{
34 Id: b.Id(),
35 CreateLamportTime: b.CreateLamportTime(),
36 EditLamportTime: b.EditLamportTime(),
37 CreateUnixTime: b.FirstOp().GetUnixTime(),
38 EditUnixTime: snap.LastEditUnix(),
39 Status: snap.Status,
40 Author: AuthorExcerpt{
41 Login: snap.Author.Login(),
42 Name: snap.Author.Name(),
43 },
44 Labels: snap.Labels,
45 CreateMetadata: b.FirstOp().AllMetadata(),
46 }
47}
48
49// Package initialisation used to register the type for (de)serialization
50func init() {
51 gob.Register(BugExcerpt{})
52}
53
54/*
55 * Sorting
56 */
57
58type BugsById []*BugExcerpt
59
60func (b BugsById) Len() int {
61 return len(b)
62}
63
64func (b BugsById) Less(i, j int) bool {
65 return b[i].Id < b[j].Id
66}
67
68func (b BugsById) Swap(i, j int) {
69 b[i], b[j] = b[j], b[i]
70}
71
72type BugsByCreationTime []*BugExcerpt
73
74func (b BugsByCreationTime) Len() int {
75 return len(b)
76}
77
78func (b BugsByCreationTime) Less(i, j int) bool {
79 if b[i].CreateLamportTime < b[j].CreateLamportTime {
80 return true
81 }
82
83 if b[i].CreateLamportTime > b[j].CreateLamportTime {
84 return false
85 }
86
87 // When the logical clocks are identical, that means we had a concurrent
88 // edition. In this case we rely on the timestamp. While the timestamp might
89 // be incorrect due to a badly set clock, the drift in sorting is bounded
90 // by the first sorting using the logical clock. That means that if users
91 // synchronize their bugs regularly, the timestamp will rarely be used, and
92 // should still provide a kinda accurate sorting when needed.
93 return b[i].CreateUnixTime < b[j].CreateUnixTime
94}
95
96func (b BugsByCreationTime) Swap(i, j int) {
97 b[i], b[j] = b[j], b[i]
98}
99
100type BugsByEditTime []*BugExcerpt
101
102func (b BugsByEditTime) Len() int {
103 return len(b)
104}
105
106func (b BugsByEditTime) Less(i, j int) bool {
107 if b[i].EditLamportTime < b[j].EditLamportTime {
108 return true
109 }
110
111 if b[i].EditLamportTime > b[j].EditLamportTime {
112 return false
113 }
114
115 // When the logical clocks are identical, that means we had a concurrent
116 // edition. In this case we rely on the timestamp. While the timestamp might
117 // be incorrect due to a badly set clock, the drift in sorting is bounded
118 // by the first sorting using the logical clock. That means that if users
119 // synchronize their bugs regularly, the timestamp will rarely be used, and
120 // should still provide a kinda accurate sorting when needed.
121 return b[i].EditUnixTime < b[j].EditUnixTime
122}
123
124func (b BugsByEditTime) Swap(i, j int) {
125 b[i], b[j] = b[j], b[i]
126}