github.com/kayoticsully/syncthing@v0.8.9-0.20140724133906-c45a2fdc03f8/model/blockqueue.go (about)

     1  // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
     2  // All rights reserved. Use of this source code is governed by an MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package model
     6  
     7  import "github.com/calmh/syncthing/protocol"
     8  
     9  type bqAdd struct {
    10  	file protocol.FileInfo
    11  	have []protocol.BlockInfo
    12  	need []protocol.BlockInfo
    13  }
    14  
    15  type bqBlock struct {
    16  	file  protocol.FileInfo
    17  	block protocol.BlockInfo   // get this block from the network
    18  	copy  []protocol.BlockInfo // copy these blocks from the old version of the file
    19  	first bool
    20  	last  bool
    21  }
    22  
    23  type blockQueue struct {
    24  	queued []bqBlock
    25  }
    26  
    27  func (q *blockQueue) put(a bqAdd) {
    28  	// If we already have it queued, return
    29  	for _, b := range q.queued {
    30  		if b.file.Name == a.file.Name {
    31  			return
    32  		}
    33  	}
    34  
    35  	l := len(a.need)
    36  
    37  	if len(a.have) > 0 {
    38  		// First queue a copy operation
    39  		q.queued = append(q.queued, bqBlock{
    40  			file:  a.file,
    41  			copy:  a.have,
    42  			first: true,
    43  			last:  l == 0,
    44  		})
    45  	}
    46  
    47  	// Queue the needed blocks individually
    48  	for i, b := range a.need {
    49  		q.queued = append(q.queued, bqBlock{
    50  			file:  a.file,
    51  			block: b,
    52  			first: len(a.have) == 0 && i == 0,
    53  			last:  i == l-1,
    54  		})
    55  	}
    56  
    57  	if len(a.need)+len(a.have) == 0 {
    58  		// If we didn't have anything to fetch, queue an empty block with the "last" flag set to close the file.
    59  		q.queued = append(q.queued, bqBlock{
    60  			file: a.file,
    61  			last: true,
    62  		})
    63  	}
    64  }
    65  
    66  func (q *blockQueue) get() (bqBlock, bool) {
    67  	if len(q.queued) == 0 {
    68  		return bqBlock{}, false
    69  	}
    70  	b := q.queued[0]
    71  	q.queued = q.queued[1:]
    72  	return b, true
    73  }