/
cache.go
126 lines (114 loc) · 2.3 KB
/
cache.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package main
import (
"bytes"
"code.google.com/p/go-avltree/trunk"
"io"
"os"
"strings"
"stringsim/adjpair"
"sync/atomic"
"syscall"
)
type SimilarDir struct {
// directory name
dir string
// pairs
pairs adjpair.Pairs
// similarity index
six float64
}
// reverse comparsion
func (o SimilarDir) Compare(b avltree.Interface) int {
if o.six > b.(SimilarDir).six {
return -1
}
if o.six < b.(SimilarDir).six {
return 1
}
return 0
}
type Cache struct {
map_file *os.File
buffer []byte
}
type CacheReader struct {
cache *Cache
terminate *int32
}
func OpenCache(filename string) (*Cache, error) {
cache := new(Cache)
file, err := os.Open(filename)
if err != nil {
return nil, err
}
cache.map_file = file
stat, err := cache.map_file.Stat()
if err != nil {
return nil, err
}
buffer, err := syscall.Mmap((int)(cache.map_file.Fd()), 0, (int)(stat.Size()), syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
return nil, err
}
cache.buffer = buffer
return cache, nil
}
func NewCacheReader(cache *Cache) *CacheReader {
return &CacheReader{cache: cache, terminate: new(int32)}
}
func (creader *CacheReader) isTerminating() bool {
return atomic.LoadInt32(creader.terminate) != 0
}
func (creader *CacheReader) setTerminate(value bool) {
if value {
atomic.StoreInt32(creader.terminate, 1)
} else {
atomic.StoreInt32(creader.terminate, 0)
}
}
func (creader *CacheReader) Read(out chan *SimilarDir) error {
creader.setTerminate(false)
buffer := bytes.NewBuffer(creader.cache.buffer)
for {
path, err := buffer.ReadString(0)
if err == io.EOF || creader.isTerminating() {
close(out)
break
} else if err != nil {
return err
}
out <- &SimilarDir{strings.TrimSpace(path), nil, 0.0}
}
return nil
}
func (cache *Cache) Close() error {
err := syscall.Munmap(cache.buffer)
if err != nil {
return err
}
err = cache.map_file.Close()
if err != nil {
return err
}
return nil
}
/*
// simple implementation
func ReadCache2(filename string, out chan *SimilarDir) error {
f, err := os.Open(filename)
defer f.Close()
r := bufio.NewReader(f)
for {
path, err := r.ReadString(0)
if err == io.EOF {
out <-&LAST_DIR
break
} else if err != nil {
return err
}
dir := SimilarDir{strings.TrimSpace(path), nil, 0.0}
out <-&dir
}
return nil
}
*/