File: backlog.go

package info (click to toggle)
reflex 0.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 164 kB
  • sloc: makefile: 4
file content (108 lines) | stat: -rw-r--r-- 2,442 bytes parent folder | download | duplicates (3)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main

// A Backlog represents a queue of file paths that may be received while we're
// still running a command. There are a couple of different policies for how to
// handle this. If there are no {} (substitution sequences) in the command, then
// we only need to preserve one of the paths. If there is a {}, then we need to
// preserve each unique path in the backlog.
type Backlog interface {
	// Add a path to the backlog.
	Add(path string)
	// Show what path should be processed next.
	Next() string
	// Remove the next path from the backlog and return whether
	// the backlog is now empty.
	RemoveOne() (empty bool)
}

// A UnifiedBacklog only remembers one backlog item at a time.
type UnifiedBacklog struct {
	s     string
	empty bool
}

func NewUnifiedBacklog() *UnifiedBacklog {
	return &UnifiedBacklog{empty: true}
}

// Add adds path to b if there is not a path there currently.
// Otherwise it discards it.
func (b *UnifiedBacklog) Add(path string) {
	if b.empty {
		b.s = path
		b.empty = false
	}
}

// Next returns the path in b.
func (b *UnifiedBacklog) Next() string {
	if b.empty {
		panic("Next() called on empty backlog")
	}
	return b.s
}

// RemoveOne removes the path in b.
func (b *UnifiedBacklog) RemoveOne() bool {
	if b.empty {
		panic("RemoveOne() called on empty backlog")
	}
	b.empty = true
	b.s = ""
	return true
}

// A UniqueFilesBacklog keeps a set of the paths it has received.
type UniqueFilesBacklog struct {
	empty bool
	next  string
	rest  map[string]struct{}
}

func NewUniqueFilesBacklog() *UniqueFilesBacklog {
	return &UniqueFilesBacklog{
		empty: true,
		next:  "",
		rest:  make(map[string]struct{}),
	}
}

// Add adds path to the set of files in b.
func (b *UniqueFilesBacklog) Add(path string) {
	defer func() { b.empty = false }()
	if b.empty {
		b.next = path
		return
	}
	if path == b.next {
		return
	}
	b.rest[path] = struct{}{}
}

// Next returns one of the paths in b.
func (b *UniqueFilesBacklog) Next() string {
	if b.empty {
		panic("Next() called on empty backlog")
	}
	return b.next
}

// RemoveOne removes one of the paths from b (the same path that was returned by
// a preceding call to Next).
func (b *UniqueFilesBacklog) RemoveOne() bool {
	if b.empty {
		panic("RemoveOne() called on empty backlog")
	}
	if len(b.rest) == 0 {
		b.next = ""
		b.empty = true
		return true
	}
	for next := range b.rest {
		b.next = next
		break
	}
	delete(b.rest, b.next)
	return false
}