2
0

config_diff.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. if len(oList) != 0 && len(nList) != 0 {
  46. // insert a tail node to both lists
  47. // as the maximum node
  48. lastOld, lastNew := oList[len(oList)-1], nList[len(nList)-1]
  49. maxName := lastOld.Name
  50. if lastNew.Name > lastOld.Name {
  51. maxName = lastNew.Name
  52. }
  53. Nil := mirrorConfig{Name: "~" + maxName}
  54. if Nil.Name <= maxName {
  55. panic("Nil.Name should be larger than maxName")
  56. }
  57. oList, nList = append(oList, Nil), append(nList, Nil)
  58. // iterate over both lists to find the difference
  59. for i, j := 0, 0; i < len(oList) && j < len(nList); {
  60. o, n := oList[i], nList[j]
  61. if n.Name < o.Name {
  62. operations = append(operations, mirrorCfgTrans{diffAdd, n})
  63. j++
  64. } else if o.Name < n.Name {
  65. operations = append(operations, mirrorCfgTrans{diffDelete, o})
  66. i++
  67. } else {
  68. if !reflect.DeepEqual(o, n) {
  69. operations = append(operations, mirrorCfgTrans{diffModify, n})
  70. }
  71. i++
  72. j++
  73. }
  74. }
  75. } else {
  76. for i := 0; i < len(oList); i++ {
  77. operations = append(operations, mirrorCfgTrans{diffDelete, oList[i]})
  78. }
  79. for i := 0; i < len(nList); i++ {
  80. operations = append(operations, mirrorCfgTrans{diffAdd, nList[i]})
  81. }
  82. }
  83. return operations
  84. }