本站源代码
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

129 行
2.0KB

  1. package nodb
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. "github.com/lunny/log"
  7. "github.com/lunny/nodb/config"
  8. "github.com/lunny/nodb/store"
  9. )
  10. type Nodb struct {
  11. cfg *config.Config
  12. ldb *store.DB
  13. dbs [MaxDBNumber]*DB
  14. quit chan struct{}
  15. jobs *sync.WaitGroup
  16. binlog *BinLog
  17. wLock sync.RWMutex //allow one write at same time
  18. commitLock sync.Mutex //allow one write commit at same time
  19. }
  20. func Open(cfg *config.Config) (*Nodb, error) {
  21. if len(cfg.DataDir) == 0 {
  22. cfg.DataDir = config.DefaultDataDir
  23. }
  24. ldb, err := store.Open(cfg)
  25. if err != nil {
  26. return nil, err
  27. }
  28. l := new(Nodb)
  29. l.quit = make(chan struct{})
  30. l.jobs = new(sync.WaitGroup)
  31. l.ldb = ldb
  32. if cfg.BinLog.MaxFileNum > 0 && cfg.BinLog.MaxFileSize > 0 {
  33. l.binlog, err = NewBinLog(cfg)
  34. if err != nil {
  35. return nil, err
  36. }
  37. } else {
  38. l.binlog = nil
  39. }
  40. for i := uint8(0); i < MaxDBNumber; i++ {
  41. l.dbs[i] = l.newDB(i)
  42. }
  43. l.activeExpireCycle()
  44. return l, nil
  45. }
  46. func (l *Nodb) Close() {
  47. close(l.quit)
  48. l.jobs.Wait()
  49. l.ldb.Close()
  50. if l.binlog != nil {
  51. l.binlog.Close()
  52. l.binlog = nil
  53. }
  54. }
  55. func (l *Nodb) Select(index int) (*DB, error) {
  56. if index < 0 || index >= int(MaxDBNumber) {
  57. return nil, fmt.Errorf("invalid db index %d", index)
  58. }
  59. return l.dbs[index], nil
  60. }
  61. func (l *Nodb) FlushAll() error {
  62. for index, db := range l.dbs {
  63. if _, err := db.FlushAll(); err != nil {
  64. log.Error("flush db %d error %s", index, err.Error())
  65. }
  66. }
  67. return nil
  68. }
  69. // very dangerous to use
  70. func (l *Nodb) DataDB() *store.DB {
  71. return l.ldb
  72. }
  73. func (l *Nodb) activeExpireCycle() {
  74. var executors []*elimination = make([]*elimination, len(l.dbs))
  75. for i, db := range l.dbs {
  76. executors[i] = db.newEliminator()
  77. }
  78. l.jobs.Add(1)
  79. go func() {
  80. tick := time.NewTicker(1 * time.Second)
  81. end := false
  82. done := make(chan struct{})
  83. for !end {
  84. select {
  85. case <-tick.C:
  86. go func() {
  87. for _, eli := range executors {
  88. eli.active()
  89. }
  90. done <- struct{}{}
  91. }()
  92. <-done
  93. case <-l.quit:
  94. end = true
  95. break
  96. }
  97. }
  98. tick.Stop()
  99. l.jobs.Done()
  100. }()
  101. }
上海开阖软件有限公司 沪ICP备12045867号-1