2
0

config_diff.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package worker
  2. import (
  3. "fmt"
  4. "reflect"
  5. "sort"
  6. )
  7. // Find difference of mirror config, this is important for hot reloading config file
  8. // NOTICE: only the [[mirrors]] section is supported
  9. // make []mirrorConfig sortable
  10. type sortableMirrorList []mirrorConfig
  11. func (l sortableMirrorList) Len() int { return len(l) }
  12. func (l sortableMirrorList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
  13. func (l sortableMirrorList) Less(i, j int) bool { return l[i].Name < l[j].Name }
  14. const (
  15. diffDelete uint8 = iota
  16. diffAdd
  17. diffModify
  18. )
  19. // a unit of mirror config difference
  20. type mirrorCfgTrans struct {
  21. diffOp uint8
  22. mirCfg mirrorConfig
  23. }
  24. func (t mirrorCfgTrans) String() string {
  25. var op string
  26. if t.diffOp == diffDelete {
  27. op = "Del"
  28. } else {
  29. op = "Add"
  30. }
  31. return fmt.Sprintf("{%s, %s}", op, t.mirCfg.Name)
  32. }
  33. // diffMirrorConfig finds the difference between the oldList and the newList
  34. // it returns a series of operations that if these operations are applied to
  35. // oldList, a newList equavuilance can be obtained.
  36. func diffMirrorConfig(oldList, newList []mirrorConfig) []mirrorCfgTrans {
  37. operations := []mirrorCfgTrans{}
  38. oList := make([]mirrorConfig, len(oldList))
  39. nList := make([]mirrorConfig, len(newList))
  40. copy(oList, oldList)
  41. copy(nList, newList)
  42. // first ensure oldList and newList are sorted
  43. sort.Sort(sortableMirrorList(oList))
  44. sort.Sort(sortableMirrorList(nList))
  45. // insert a tail node to both lists
  46. // as the maximum node
  47. lastOld, lastNew := oList[len(oList)-1], nList[len(nList)-1]
  48. maxName := lastOld.Name
  49. if lastNew.Name > lastOld.Name {
  50. maxName = lastNew.Name
  51. }
  52. Nil := mirrorConfig{Name: "~" + maxName}
  53. if Nil.Name <= maxName {
  54. panic("Nil.Name should be larger than maxName")
  55. }
  56. oList, nList = append(oList, Nil), append(nList, Nil)
  57. // iterate over both lists to find the difference
  58. for i, j := 0, 0; i < len(oList) && j < len(nList); {
  59. o, n := oList[i], nList[j]
  60. if n.Name < o.Name {
  61. operations = append(operations, mirrorCfgTrans{diffAdd, n})
  62. j++
  63. } else if o.Name < n.Name {
  64. operations = append(operations, mirrorCfgTrans{diffDelete, o})
  65. i++
  66. } else {
  67. if !reflect.DeepEqual(o, n) {
  68. operations = append(operations, mirrorCfgTrans{diffModify, n})
  69. }
  70. i++
  71. j++
  72. }
  73. }
  74. return operations
  75. }