2014-07-12 22:45:33 +00:00
|
|
|
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
|
|
|
// All rights reserved. Use of this source code is governed by an MIT-style
|
|
|
|
// license that can be found in the LICENSE file.
|
2014-06-01 20:50:14 +00:00
|
|
|
|
2014-05-15 03:26:55 +00:00
|
|
|
package model
|
2014-03-28 13:36:57 +00:00
|
|
|
|
2014-09-22 19:42:11 +00:00
|
|
|
import "github.com/syncthing/syncthing/internal/protocol"
|
2014-03-28 13:36:57 +00:00
|
|
|
|
|
|
|
type bqAdd struct {
|
2014-07-12 21:06:48 +00:00
|
|
|
file protocol.FileInfo
|
|
|
|
have []protocol.BlockInfo
|
|
|
|
need []protocol.BlockInfo
|
2014-03-28 13:36:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type bqBlock struct {
|
2014-07-12 21:06:48 +00:00
|
|
|
file protocol.FileInfo
|
|
|
|
block protocol.BlockInfo // get this block from the network
|
|
|
|
copy []protocol.BlockInfo // copy these blocks from the old version of the file
|
2014-05-28 09:45:45 +00:00
|
|
|
first bool
|
2014-03-28 13:36:57 +00:00
|
|
|
last bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type blockQueue struct {
|
|
|
|
queued []bqBlock
|
|
|
|
}
|
|
|
|
|
2014-07-24 07:38:16 +00:00
|
|
|
func (q *blockQueue) put(a bqAdd) {
|
2014-03-28 13:36:57 +00:00
|
|
|
// If we already have it queued, return
|
|
|
|
for _, b := range q.queued {
|
|
|
|
if b.file.Name == a.file.Name {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2014-05-28 09:45:45 +00:00
|
|
|
|
|
|
|
l := len(a.need)
|
|
|
|
|
2014-03-28 13:36:57 +00:00
|
|
|
if len(a.have) > 0 {
|
|
|
|
// First queue a copy operation
|
|
|
|
q.queued = append(q.queued, bqBlock{
|
2014-05-28 09:45:45 +00:00
|
|
|
file: a.file,
|
|
|
|
copy: a.have,
|
|
|
|
first: true,
|
|
|
|
last: l == 0,
|
2014-03-28 13:36:57 +00:00
|
|
|
})
|
|
|
|
}
|
2014-05-28 09:45:45 +00:00
|
|
|
|
2014-03-28 13:36:57 +00:00
|
|
|
// Queue the needed blocks individually
|
|
|
|
for i, b := range a.need {
|
|
|
|
q.queued = append(q.queued, bqBlock{
|
|
|
|
file: a.file,
|
|
|
|
block: b,
|
2014-05-28 09:45:45 +00:00
|
|
|
first: len(a.have) == 0 && i == 0,
|
2014-03-28 13:36:57 +00:00
|
|
|
last: i == l-1,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-05-28 09:45:45 +00:00
|
|
|
if len(a.need)+len(a.have) == 0 {
|
2014-03-28 13:36:57 +00:00
|
|
|
// If we didn't have anything to fetch, queue an empty block with the "last" flag set to close the file.
|
|
|
|
q.queued = append(q.queued, bqBlock{
|
|
|
|
file: a.file,
|
|
|
|
last: true,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-24 07:38:16 +00:00
|
|
|
func (q *blockQueue) get() (bqBlock, bool) {
|
|
|
|
if len(q.queued) == 0 {
|
|
|
|
return bqBlock{}, false
|
2014-03-28 13:36:57 +00:00
|
|
|
}
|
2014-07-24 07:38:16 +00:00
|
|
|
b := q.queued[0]
|
|
|
|
q.queued = q.queued[1:]
|
|
|
|
return b, true
|
2014-03-28 13:36:57 +00:00
|
|
|
}
|