-
Notifications
You must be signed in to change notification settings - Fork 0
/
sdbf_factory.go
108 lines (92 loc) · 2.97 KB
/
sdbf_factory.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
package sdhash
import (
"fmt"
"io"
"io/ioutil"
"os"
"path"
"strings"
)
// SdbfFactory can be used to create a Sdbf from a binary source.
type SdbfFactory interface {
// WithBlockSize sets the block size for the block mode.
// The default value of 0 involves in a Sdbf generated in stream mode.
WithBlockSize(blockSize uint32) SdbfFactory
// WithInitialIndex sets the initial BloomFilter index.
// Without setting an initial index the factory creates a new empty BloomFilter.
WithInitialIndex(initialIndex BloomFilter) SdbfFactory
// WithSearchIndexes sets a list of BloomFilter which are checked for similarity during digesting process.
// Without setting a value the searching operation during the digesting process is disabled.
WithSearchIndexes(searchIndexes []BloomFilter) SdbfFactory
// WithName sets the name of the Sdbf in the output.
WithName(name string) SdbfFactory
// Compute start the digesting process and provide a Sdbf with the result.
Compute() Sdbf
}
type sdbfFactory struct {
buffer []uint8
ddBlockSize uint32
initialIndex BloomFilter
searchIndexes []BloomFilter
name string
}
// CreateSdbfFromFilename returns a factory which can produce a Sdbf of a file.
func CreateSdbfFromFilename(filename string) (SdbfFactory, error) {
info, err := os.Stat(filename)
if err != nil {
return nil, err
}
if !info.Mode().IsRegular() {
return nil, fmt.Errorf("%s is not a regular file", filename)
}
if info.Size() < MinFileSize {
return nil, fmt.Errorf("%s is too small", filename)
}
if buffer, err := ioutil.ReadFile(filename); err == nil {
if sdbf, err := CreateSdbfFromBytes(buffer); err != nil {
panic(err)
} else {
sdbf.WithName(path.Base(filename))
return sdbf, nil
}
} else {
return nil, err
}
}
// CreateSdbfFromBytes returns a factory which can produce a Sdbf from a bytes buffer.
func CreateSdbfFromBytes(buffer []uint8) (SdbfFactory, error) {
if len(buffer) < MinFileSize {
return nil, fmt.Errorf("the length of buffer must be greater than %d", MinFileSize)
}
return &sdbfFactory{
buffer: buffer,
}, nil
}
// CreateSdbfFromReader returns a factory which can produce a Sdbf from a io.Reader.
func CreateSdbfFromReader(r io.Reader) (SdbfFactory, error) {
var buffer []byte
var err error
if buffer, err = ioutil.ReadAll(r); err != nil {
return nil, err
}
return CreateSdbfFromBytes(buffer)
}
func (sdf *sdbfFactory) WithBlockSize(blockSize uint32) SdbfFactory {
sdf.ddBlockSize = blockSize
return sdf
}
func (sdf *sdbfFactory) WithInitialIndex(initialIndex BloomFilter) SdbfFactory {
sdf.initialIndex = initialIndex
return sdf
}
func (sdf *sdbfFactory) WithSearchIndexes(searchIndexes []BloomFilter) SdbfFactory {
sdf.searchIndexes = searchIndexes
return sdf
}
func (sdf *sdbfFactory) WithName(name string) SdbfFactory {
sdf.name = strings.ReplaceAll(name, ":", "$")
return sdf
}
func (sdf *sdbfFactory) Compute() Sdbf {
return createSdbf(sdf.buffer, sdf.ddBlockSize, sdf.initialIndex, sdf.searchIndexes, sdf.name)
}