@@ -23,10 +23,10 @@ type manifestImage struct {
23
23
offsets []int64
24
24
chunks map [string ]* chunk
25
25
written map [int64 ]bool
26
- //chunkCount map[string]int64
26
+ sliceCount map [string ]int64
27
27
}
28
28
29
- func Map (manifestFile string , store ChunkStore , targetFile string ) error {
29
+ func Map (manifestFile string , store ChunkStore , cache ChunkStore , targetFile string ) error {
30
30
manifest , err := NewManifestFromFile (manifestFile )
31
31
if err != nil {
32
32
return err
@@ -51,7 +51,7 @@ func Map(manifestFile string, store ChunkStore, targetFile string) error {
51
51
52
52
debugf ("Creating device %s ...\n " , deviceName )
53
53
54
- image := NewManifestImage (manifest , store , target )
54
+ image := NewManifestImage (manifest , store , cache , target )
55
55
device , err := buse .CreateDevice (deviceName , uint (manifest .Size ()), image )
56
56
if err != nil {
57
57
return err
@@ -61,7 +61,7 @@ func Map(manifestFile string, store ChunkStore, targetFile string) error {
61
61
signal .Notify (sig , os .Interrupt )
62
62
go func () {
63
63
if err := device .Connect (); err != nil {
64
- log . Printf ("Buse device stopped with error: %s" , err )
64
+ debugf ("Buse device stopped with error: %s" , err )
65
65
} else {
66
66
log .Println ("Buse device stopped gracefully." )
67
67
}
@@ -76,16 +76,31 @@ func Map(manifestFile string, store ChunkStore, targetFile string) error {
76
76
return nil
77
77
}
78
78
79
- func NewManifestImage (manifest * manifest , store ChunkStore , target * os.File ) * manifestImage {
79
+ func NewManifestImage (manifest * manifest , store ChunkStore , cache ChunkStore , target * os.File ) * manifestImage {
80
+ sliceCount := make (map [string ]int64 , 0 )
81
+
82
+ for _ , sliceOffset := range manifest .Offsets () {
83
+ slice := manifest .Get (sliceOffset )
84
+ if slice .checksum != nil {
85
+ checksumStr := fmt .Sprintf ("%x" , slice .checksum )
86
+
87
+ if _ , ok := sliceCount [checksumStr ]; ok {
88
+ sliceCount [checksumStr ]++
89
+ } else {
90
+ sliceCount [checksumStr ] = 1
91
+ }
92
+ }
93
+ }
94
+
80
95
return & manifestImage {
81
- manifest : manifest ,
82
- store : store ,
83
- target : target ,
84
- cache : NewFileChunkStore ( " cache" ) ,
85
- offsets : manifest .Offsets (), // cache !
86
- chunks : manifest .Chunks (), // cache !
87
- written : make (map [int64 ]bool , 0 ),
88
- // chunkCount: make(map[string]int64, 0) ,
96
+ manifest : manifest ,
97
+ store : store ,
98
+ target : target ,
99
+ cache : cache ,
100
+ offsets : manifest .Offsets (), // cache !
101
+ chunks : manifest .Chunks (), // cache !
102
+ written : make (map [int64 ]bool , 0 ),
103
+ sliceCount : sliceCount ,
89
104
}
90
105
}
91
106
@@ -116,7 +131,7 @@ func (d *manifestImage) WriteAt(p []byte, off uint) error {
116
131
return err
117
132
}
118
133
119
- log . Printf ("WRITE offset:%d len:%d\n " , off , len (p ))
134
+ debugf ("WRITE offset:%d len:%d\n " , off , len (p ))
120
135
121
136
written , err := d .target .WriteAt (p , int64 (off ))
122
137
if err != nil {
@@ -183,13 +198,14 @@ func (d *manifestImage) syncSlice(offset int64, slice *chunkSlice) error {
183
198
debugf ("Syncing diskoff %d - %d (len %d) -> checksum %x, %d to %d\n " ,
184
199
offset , offset + length , length , slice .checksum , slice .from , slice .to )
185
200
201
+ checksumStr := fmt .Sprintf ("%x" , slice .checksum )
186
202
buffer := make ([]byte , chunkSizeMaxBytes ) // FIXME: Make this a buffer pool
187
203
read , err := d .cache .ReadAt (slice .checksum , buffer [:length ], slice .from )
188
204
if err != nil {
189
205
debugf ("Chunk %x not in cache. Retrieving full chunk ...\n " , slice .checksum )
190
206
191
207
// Read entire chunk, store to cache
192
- chunk := d .chunks [fmt . Sprintf ( "%x" , slice . checksum ) ]
208
+ chunk := d .chunks [checksumStr ]
193
209
194
210
// FIXME: This will fill up the local cache will all chunks and never delete it
195
211
read , err = d .store .ReadAt (slice .checksum , buffer [:chunk .size ], 0 )
@@ -213,7 +229,16 @@ func (d *manifestImage) syncSlice(offset int64, slice *chunkSlice) error {
213
229
return err
214
230
}
215
231
232
+ // Accounting
216
233
d .written [offset ] = true
234
+ d .sliceCount [checksumStr ]--
235
+
236
+ // Remove from cache if it will never be requested again
237
+ if d .sliceCount [checksumStr ] == 0 {
238
+ if err := d .cache .Remove (slice .checksum ); err != nil {
239
+ return err
240
+ }
241
+ }
217
242
218
243
return nil
219
244
}
0 commit comments