blockqueue.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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. package model
  5. import "github.com/syncthing/syncthing/internal/protocol"
  6. type bqAdd struct {
  7. file protocol.FileInfo
  8. have []protocol.BlockInfo
  9. need []protocol.BlockInfo
  10. }
  11. type bqBlock struct {
  12. file protocol.FileInfo
  13. block protocol.BlockInfo // get this block from the network
  14. copy []protocol.BlockInfo // copy these blocks from the old version of the file
  15. first bool
  16. last bool
  17. }
  18. type blockQueue struct {
  19. queued []bqBlock
  20. }
  21. func (q *blockQueue) put(a bqAdd) {
  22. // If we already have it queued, return
  23. for _, b := range q.queued {
  24. if b.file.Name == a.file.Name {
  25. return
  26. }
  27. }
  28. l := len(a.need)
  29. if len(a.have) > 0 {
  30. // First queue a copy operation
  31. q.queued = append(q.queued, bqBlock{
  32. file: a.file,
  33. copy: a.have,
  34. first: true,
  35. last: l == 0,
  36. })
  37. }
  38. // Queue the needed blocks individually
  39. for i, b := range a.need {
  40. q.queued = append(q.queued, bqBlock{
  41. file: a.file,
  42. block: b,
  43. first: len(a.have) == 0 && i == 0,
  44. last: i == l-1,
  45. })
  46. }
  47. if len(a.need)+len(a.have) == 0 {
  48. // If we didn't have anything to fetch, queue an empty block with the "last" flag set to close the file.
  49. q.queued = append(q.queued, bqBlock{
  50. file: a.file,
  51. last: true,
  52. })
  53. }
  54. }
  55. func (q *blockQueue) get() (bqBlock, bool) {
  56. if len(q.queued) == 0 {
  57. return bqBlock{}, false
  58. }
  59. b := q.queued[0]
  60. q.queued = q.queued[1:]
  61. return b, true
  62. }