-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathdepth_holder.go
79 lines (68 loc) · 1.44 KB
/
depth_holder.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
package gitignore
import "strings"
const (
asc = iota
desc
)
type depthPatternHolder struct {
patterns depthPatterns
order int
}
func newDepthPatternHolder(order int) depthPatternHolder {
return depthPatternHolder{
patterns: depthPatterns{m: map[int]initialPatternHolder{}},
order: order,
}
}
func (h *depthPatternHolder) add(pattern string) {
count := strings.Count(strings.Trim(pattern, "/"), "/")
h.patterns.set(count+1, pattern)
}
func (h depthPatternHolder) match(path string, isDir bool) bool {
if h.patterns.size() == 0 {
return false
}
for depth := 1; ; depth++ {
var part string
var isLast, isDirCurrent bool
if h.order == asc {
part, isLast = cutN(path, depth)
if isLast {
isDirCurrent = isDir
} else {
isDirCurrent = false
}
} else {
part, isLast = cutLastN(path, depth)
isDirCurrent = isDir
}
if patterns, ok := h.patterns.get(depth); ok {
if patterns.match(part, isDirCurrent) {
return true
}
}
if isLast {
break
}
}
return false
}
type depthPatterns struct {
m map[int]initialPatternHolder
}
func (p *depthPatterns) set(depth int, pattern string) {
if ps, ok := p.m[depth]; ok {
ps.add(pattern)
} else {
holder := newInitialPatternHolder()
holder.add(pattern)
p.m[depth] = holder
}
}
func (p depthPatterns) get(depth int) (initialPatternHolder, bool) {
patterns, ok := p.m[depth]
return patterns, ok
}
func (p depthPatterns) size() int {
return len(p.m)
}