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.

manager_leveldb.go 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package nosql
  5. import (
  6. "path"
  7. "strconv"
  8. "strings"
  9. "github.com/syndtr/goleveldb/leveldb"
  10. "github.com/syndtr/goleveldb/leveldb/errors"
  11. "github.com/syndtr/goleveldb/leveldb/opt"
  12. )
  13. // CloseLevelDB closes a levelDB
  14. func (m *Manager) CloseLevelDB(connection string) error {
  15. m.mutex.Lock()
  16. defer m.mutex.Unlock()
  17. db, ok := m.LevelDBConnections[connection]
  18. if !ok {
  19. connection = ToLevelDBURI(connection).String()
  20. db, ok = m.LevelDBConnections[connection]
  21. }
  22. if !ok {
  23. return nil
  24. }
  25. db.count--
  26. if db.count > 0 {
  27. return nil
  28. }
  29. for _, name := range db.name {
  30. delete(m.LevelDBConnections, name)
  31. }
  32. return db.db.Close()
  33. }
  34. // GetLevelDB gets a levelDB for a particular connection
  35. func (m *Manager) GetLevelDB(connection string) (*leveldb.DB, error) {
  36. m.mutex.Lock()
  37. defer m.mutex.Unlock()
  38. db, ok := m.LevelDBConnections[connection]
  39. if ok {
  40. db.count++
  41. return db.db, nil
  42. }
  43. uri := ToLevelDBURI(connection)
  44. db = &levelDBHolder{
  45. name: []string{connection, uri.String()},
  46. }
  47. dataDir := path.Join(uri.Host, uri.Path)
  48. opts := &opt.Options{}
  49. for k, v := range uri.Query() {
  50. switch replacer.Replace(strings.ToLower(k)) {
  51. case "blockcachecapacity":
  52. opts.BlockCacheCapacity, _ = strconv.Atoi(v[0])
  53. case "blockcacheevictremoved":
  54. opts.BlockCacheEvictRemoved, _ = strconv.ParseBool(v[0])
  55. case "blockrestartinterval":
  56. opts.BlockRestartInterval, _ = strconv.Atoi(v[0])
  57. case "blocksize":
  58. opts.BlockSize, _ = strconv.Atoi(v[0])
  59. case "compactionexpandlimitfactor":
  60. opts.CompactionExpandLimitFactor, _ = strconv.Atoi(v[0])
  61. case "compactiongpoverlapsfactor":
  62. opts.CompactionGPOverlapsFactor, _ = strconv.Atoi(v[0])
  63. case "compactionl0trigger":
  64. opts.CompactionL0Trigger, _ = strconv.Atoi(v[0])
  65. case "compactionsourcelimitfactor":
  66. opts.CompactionSourceLimitFactor, _ = strconv.Atoi(v[0])
  67. case "compactiontablesize":
  68. opts.CompactionTableSize, _ = strconv.Atoi(v[0])
  69. case "compactiontablesizemultiplier":
  70. opts.CompactionTableSizeMultiplier, _ = strconv.ParseFloat(v[0], 64)
  71. case "compactiontablesizemultiplierperlevel":
  72. for _, val := range v {
  73. f, _ := strconv.ParseFloat(val, 64)
  74. opts.CompactionTableSizeMultiplierPerLevel = append(opts.CompactionTableSizeMultiplierPerLevel, f)
  75. }
  76. case "compactiontotalsize":
  77. opts.CompactionTotalSize, _ = strconv.Atoi(v[0])
  78. case "compactiontotalsizemultiplier":
  79. opts.CompactionTotalSizeMultiplier, _ = strconv.ParseFloat(v[0], 64)
  80. case "compactiontotalsizemultiplierperlevel":
  81. for _, val := range v {
  82. f, _ := strconv.ParseFloat(val, 64)
  83. opts.CompactionTotalSizeMultiplierPerLevel = append(opts.CompactionTotalSizeMultiplierPerLevel, f)
  84. }
  85. case "compression":
  86. val, _ := strconv.Atoi(v[0])
  87. opts.Compression = opt.Compression(val)
  88. case "disablebufferpool":
  89. opts.DisableBufferPool, _ = strconv.ParseBool(v[0])
  90. case "disableblockcache":
  91. opts.DisableBlockCache, _ = strconv.ParseBool(v[0])
  92. case "disablecompactionbackoff":
  93. opts.DisableCompactionBackoff, _ = strconv.ParseBool(v[0])
  94. case "disablelargebatchtransaction":
  95. opts.DisableLargeBatchTransaction, _ = strconv.ParseBool(v[0])
  96. case "errorifexist":
  97. opts.ErrorIfExist, _ = strconv.ParseBool(v[0])
  98. case "errorifmissing":
  99. opts.ErrorIfMissing, _ = strconv.ParseBool(v[0])
  100. case "iteratorsamplingrate":
  101. opts.IteratorSamplingRate, _ = strconv.Atoi(v[0])
  102. case "nosync":
  103. opts.NoSync, _ = strconv.ParseBool(v[0])
  104. case "nowritemerge":
  105. opts.NoWriteMerge, _ = strconv.ParseBool(v[0])
  106. case "openfilescachecapacity":
  107. opts.OpenFilesCacheCapacity, _ = strconv.Atoi(v[0])
  108. case "readonly":
  109. opts.ReadOnly, _ = strconv.ParseBool(v[0])
  110. case "strict":
  111. val, _ := strconv.Atoi(v[0])
  112. opts.Strict = opt.Strict(val)
  113. case "writebuffer":
  114. opts.WriteBuffer, _ = strconv.Atoi(v[0])
  115. case "writel0pausetrigger":
  116. opts.WriteL0PauseTrigger, _ = strconv.Atoi(v[0])
  117. case "writel0slowdowntrigger":
  118. opts.WriteL0SlowdownTrigger, _ = strconv.Atoi(v[0])
  119. case "clientname":
  120. db.name = append(db.name, v[0])
  121. }
  122. }
  123. var err error
  124. db.db, err = leveldb.OpenFile(dataDir, opts)
  125. if err != nil {
  126. if !errors.IsCorrupted(err) {
  127. return nil, err
  128. }
  129. db.db, err = leveldb.RecoverFile(dataDir, opts)
  130. if err != nil {
  131. return nil, err
  132. }
  133. }
  134. for _, name := range db.name {
  135. m.LevelDBConnections[name] = db
  136. }
  137. db.count++
  138. return db.db, nil
  139. }