util.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package raft
  2. import (
  3. "fmt"
  4. "io"
  5. "math/rand"
  6. "os"
  7. "time"
  8. )
  9. // uint64Slice implements sort interface
  10. type uint64Slice []uint64
  11. func (p uint64Slice) Len() int { return len(p) }
  12. func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
  13. func (p uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  14. // WriteFile writes data to a file named by filename.
  15. // If the file does not exist, WriteFile creates it with permissions perm;
  16. // otherwise WriteFile truncates it before writing.
  17. // This is copied from ioutil.WriteFile with the addition of a Sync call to
  18. // ensure the data reaches the disk.
  19. func writeFileSynced(filename string, data []byte, perm os.FileMode) error {
  20. f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  21. if err != nil {
  22. return err
  23. }
  24. n, err := f.Write(data)
  25. if n < len(data) {
  26. f.Close()
  27. return io.ErrShortWrite
  28. }
  29. err = f.Sync()
  30. if err != nil {
  31. return err
  32. }
  33. return f.Close()
  34. }
  35. // Waits for a random time between two durations and sends the current time on
  36. // the returned channel.
  37. func afterBetween(min time.Duration, max time.Duration) <-chan time.Time {
  38. rand := rand.New(rand.NewSource(time.Now().UnixNano()))
  39. d, delta := min, (max - min)
  40. if delta > 0 {
  41. d += time.Duration(rand.Int63n(int64(delta)))
  42. }
  43. return time.After(d)
  44. }
  45. // TODO(xiangli): Remove assertions when we reach version 1.0
  46. // _assert will panic with a given formatted message if the given condition is false.
  47. func _assert(condition bool, msg string, v ...interface{}) {
  48. if !condition {
  49. panic(fmt.Sprintf("assertion failed: "+msg, v...))
  50. }
  51. }