You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
1.8 KiB

  1. package sequence
  2. import (
  3. "encoding/gob"
  4. "log"
  5. "os"
  6. "path"
  7. "sync"
  8. )
  9. const (
  10. FileIdSaveInterval = 10000
  11. )
  12. type Sequencer interface {
  13. NextFileId(count int) (uint64, int)
  14. }
  15. type SequencerImpl struct {
  16. dir string
  17. fileName string
  18. volumeLock sync.Mutex
  19. sequenceLock sync.Mutex
  20. FileIdSequence uint64
  21. fileIdCounter uint64
  22. }
  23. func NewSequencer(dirname string, filename string) (m *SequencerImpl) {
  24. m = &SequencerImpl{dir: dirname, fileName: filename}
  25. seqFile, se := os.OpenFile(path.Join(m.dir, m.fileName+".seq"), os.O_RDONLY, 0644)
  26. if se != nil {
  27. m.FileIdSequence = FileIdSaveInterval
  28. log.Println("Setting file id sequence", m.FileIdSequence)
  29. } else {
  30. decoder := gob.NewDecoder(seqFile)
  31. defer seqFile.Close()
  32. decoder.Decode(&m.FileIdSequence)
  33. log.Println("Loading file id sequence", m.FileIdSequence, "=>", m.FileIdSequence+FileIdSaveInterval)
  34. //in case the server stops between intervals
  35. m.FileIdSequence += FileIdSaveInterval
  36. }
  37. return
  38. }
  39. //count should be 1 or more
  40. func (m *SequencerImpl) NextFileId(count int) (uint64, int) {
  41. if count <= 0 {
  42. return 0, 0
  43. }
  44. m.sequenceLock.Lock()
  45. defer m.sequenceLock.Unlock()
  46. if m.fileIdCounter < uint64(count) {
  47. m.fileIdCounter = FileIdSaveInterval
  48. m.FileIdSequence += FileIdSaveInterval
  49. m.saveSequence()
  50. }
  51. m.fileIdCounter = m.fileIdCounter - uint64(count)
  52. return m.FileIdSequence - m.fileIdCounter, count
  53. }
  54. func (m *SequencerImpl) saveSequence() {
  55. log.Println("Saving file id sequence", m.FileIdSequence, "to", path.Join(m.dir, m.fileName+".seq"))
  56. seqFile, e := os.OpenFile(path.Join(m.dir, m.fileName+".seq"), os.O_CREATE|os.O_WRONLY, 0644)
  57. if e != nil {
  58. log.Fatalf("Sequence File Save [ERROR] %s\n", e)
  59. }
  60. defer seqFile.Close()
  61. encoder := gob.NewEncoder(seqFile)
  62. encoder.Encode(m.FileIdSequence)
  63. }