/
blocks.go
153 lines (139 loc) · 3.89 KB
/
blocks.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Package blocks contains the lowest level of IPLD data structures.
// A block is raw data accompanied by a CID. The CID contains the multihash
// corresponding to the block.
package blocks
import (
"errors"
"fmt"
hc "github.com/897243839/HcdComp"
cid "github.com/ipfs/go-cid"
dshelp "github.com/ipfs/go-ipfs-ds-help"
u "github.com/ipfs/go-ipfs-util"
mh "github.com/multiformats/go-multihash"
"time"
)
// ErrWrongHash is returned when the Cid of a block is not the expected
// according to the contents. It is currently used only when debugging.
var ErrWrongHash = errors.New("data did not match given hash")
// Block provides abstraction for blocks implementations.
type Block interface {
RawData() []byte
Cid() cid.Cid
String() string
Loggable() map[string]interface{}
}
// A BasicBlock is a singular block of data in ipfs. It implements the Block
// interface.
type BasicBlock struct {
cid cid.Cid
data []byte
}
// NewBlock creates a Block object from opaque data. It will hash the data.
func NewBlock(data []byte) *BasicBlock {
// TODO: fix assumptions
println("NewBlock-压缩类型", hc.GetCompressorType(data))
return &BasicBlock{data: data, cid: cid.NewCidV0(u.Hash(data))}
}
func AutoHC(data []byte, c cid.Cid) []byte {
//start := time.Now().UnixNano()
key := dshelp.MultihashToDsKey(c.Hash()).String()[1:]
startTime3 := time.Now().UnixNano()
tp := hc.GetCompressorType(data)
endTime3 := time.Now().UnixNano()
dur3 := endTime3 - startTime3
println("gettype-time:", dur3)
//println(tp)
if tp != hc.UnknownCompressor {
println("1-ZLIB", tp)
startTime1 := time.Now().UnixNano()
data = hc.Decompress(data, tp)
v, ok := hc.MapLit.Get(key)
if !ok {
hc.MapLit.Set(key, 1)
}
if v == 5 {
hc.Tsf <- key
v += 1
hc.MapLit.Set(key, v)
} else if v < 5 {
v += 1
hc.MapLit.Set(key, v)
}
endTime1 := time.Now().UnixNano()
dur1 := endTime1 - startTime1
println("mapcool-time:", dur1)
return data
} else {
startTime := time.Now().UnixNano()
v, ok := hc.Maphot.Get(key)
if !ok {
hc.Maphot.Set(key, 1)
}
if v > 999 {
} else {
v += 1
hc.Maphot.Set(key, v)
}
endTime := time.Now().UnixNano()
dur := endTime - startTime
println("maphot-time:", dur)
println("0-ipfs", tp)
}
//endT := time.Now().UnixNano()
//durt := endT - start
//println("sum-time:", durt)
//println("0-ipfs", tp)
return data
}
// NewBlockWithCid creates a new block when the hash of the data
// is already known, this is used to save time in situations where
// we are able to be confident that the data is correct.
func NewBlockWithCid(data []byte, c cid.Cid) (*BasicBlock, error) {
//println("NewBlockWithCid.cid=", dshelp.MultihashToDsKey(c.Hash()).String()[1:])
if u.Debug {
chkc, err := c.Prefix().Sum(data)
if err != nil {
return nil, err
}
if !chkc.Equals(c) {
return nil, ErrWrongHash
}
}
data = AutoHC(data, c)
return &BasicBlock{data: data, cid: c}, nil
}
func NewBlockWithCid1(data []byte, c cid.Cid) (*BasicBlock, error) {
//println("NewBlockWithCid.cid=", dshelp.MultihashToDsKey(c.Hash()).String()[1:])
if u.Debug {
chkc, err := c.Prefix().Sum(data)
if err != nil {
return nil, err
}
if !chkc.Equals(c) {
return nil, ErrWrongHash
}
}
return &BasicBlock{data: data, cid: c}, nil
}
// Multihash returns the hash contained in the block CID.
func (b *BasicBlock) Multihash() mh.Multihash {
return b.cid.Hash()
}
// RawData returns the block raw contents as a byte slice.
func (b *BasicBlock) RawData() []byte {
return b.data
}
// Cid returns the content identifier of the block.
func (b *BasicBlock) Cid() cid.Cid {
return b.cid
}
// String provides a human-readable representation of the block CID.
func (b *BasicBlock) String() string {
return fmt.Sprintf("[Block %s]", b.Cid())
}
// Loggable returns a go-log loggable item.
func (b *BasicBlock) Loggable() map[string]interface{} {
return map[string]interface{}{
"block": b.Cid().String(),
}
}