search.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // This file will just have the search functions.
  2. // Note that the deprecated versions are still kept around, just in case I need to figure out again
  3. // how iterators work...
  4. // (gwyneth 20211102)
  5. package main
  6. import (
  7. "encoding/json"
  8. "time"
  9. "github.com/dgraph-io/badger/v3"
  10. "github.com/syndtr/goleveldb/leveldb"
  11. "github.com/tidwall/buntdb"
  12. )
  13. // searchKVname searches the KV database for an avatar name.
  14. func searchKVname(avatarName string) (uuid string, grid string) {
  15. _, tempUUID, tempGrid := searchKV(avatarName)
  16. return tempUUID, tempGrid
  17. }
  18. // searchKVname searches the KV database for an avatar name.
  19. func searchKVUUID(avatarKey string) (name string, grid string) {
  20. tempAvatarName, _, tempGrid := searchKV(avatarKey)
  21. return tempAvatarName, tempGrid
  22. }
  23. /* deprecated (gwyneth 20211031)
  24. // searchKVname searches the KV database for an avatar name.
  25. func searchKVname(avatarName string) (UUID string, grid string) {
  26. var val = avatarUUID{ avatarName, uuid.Nil, "" }
  27. time_start := time.Now()
  28. var err error // to deal with scope issues
  29. switch *goslConfig.database {
  30. case "badger":
  31. kv, err := badger.Open(Opt)
  32. checkErrPanic(err)
  33. defer kv.Close()
  34. err = kv.View(func(txn *badger.Txn) error {
  35. item, err := txn.Get([]byte(avatarName))
  36. if err != nil {
  37. return err
  38. }
  39. data, err := item.ValueCopy(nil)
  40. if err != nil {
  41. log.Errorf("error %q while getting data from %v\n", err, item)
  42. return err
  43. }
  44. if err = json.Unmarshal(data, &val); err != nil {
  45. log.Errorf("error while unparsing UUID for name: %q (%v)\n", avatarName, err)
  46. return err
  47. }
  48. return nil
  49. })
  50. checkErr(err)
  51. case "buntdb":
  52. db, err := buntdb.Open(goslConfig.dbNamePath)
  53. checkErrPanic(err)
  54. defer db.Close()
  55. var data string
  56. err = db.View(func(tx *buntdb.Tx) error {
  57. data, err = tx.Get(avatarName)
  58. return err
  59. })
  60. err = json.Unmarshal([]byte(data), &val)
  61. if err != nil {
  62. log.Errorf("error while unparsing UUID for name: %q (%v)\n", avatarName, err)
  63. }
  64. case "leveldb":
  65. db, err := leveldb.OpenFile(goslConfig.dbNamePath, nil)
  66. checkErrPanic(err)
  67. defer db.Close()
  68. data, err := db.Get([]byte(avatarName), nil)
  69. if err != nil {
  70. log.Errorf("error while getting UUID for name: %q (%v)\n", avatarName, err)
  71. } else {
  72. if err = json.Unmarshal(data, &val); err != nil {
  73. log.Errorf("error while unparsing UUID for name: %q (%v)\n", avatarName, err)
  74. }
  75. }
  76. }
  77. log.Debugf("time to lookup %q: %v\n", avatarName, time.Since(time_start))
  78. if err != nil {
  79. return uuid.Nil, ""
  80. } // else:
  81. return val.UUID, val.Grid
  82. }
  83. // searchKVUUID searches the KV database for an avatar key.
  84. func searchKVUUID(avatarKey string) (name string, grid string) {
  85. time_start := time.Now()
  86. checks := 0
  87. var val = avatarUUID{ "", avatarKey, "" }
  88. var found string
  89. switch *goslConfig.database {
  90. case "badger":
  91. kv, err := badger.Open(Opt)
  92. checkErr(err) // should probably panic
  93. itOpt := badger.DefaultIteratorOptions
  94. //
  95. // if !*goslConfig.noMemory {
  96. // itOpt.PrefetchValues = true
  97. // itOpt.PrefetchSize = 1000 // attempt to get this a little bit more efficient; we have many small entries, so this is not too much
  98. // } else {
  99. //
  100. itOpt.PrefetchValues = false // allegedly this is supposed to be WAY faster...
  101. // }
  102. txn := kv.NewTransaction(true)
  103. defer txn.Discard()
  104. err = kv.View(func(txn *badger.Txn) error {
  105. itr := txn.NewIterator(itOpt)
  106. defer itr.Close()
  107. for itr.Rewind(); itr.Valid(); itr.Next() {
  108. item := itr.Item()
  109. data, err := item.ValueCopy(nil)
  110. if err != nil {
  111. log.Errorf("error %q while getting data from %v\n", err, item)
  112. return err
  113. }
  114. if err = json.Unmarshal(data, &val); err != nil {
  115. log.Errorf("error %q while unparsing UUID for data: %v\n", err, data)
  116. return err
  117. }
  118. checks++ //Just to see how many checks we made, for statistical purposes
  119. if avatarKey == val.UUID {
  120. found = string(item.Key())
  121. break
  122. }
  123. }
  124. return nil
  125. })
  126. checkErr(err)
  127. kv.Close()
  128. case "buntdb":
  129. db, err := buntdb.Open(goslConfig.dbNamePath)
  130. checkErrPanic(err)
  131. err = db.View(func(tx *buntdb.Tx) error {
  132. err := tx.Ascend("", func(key, value string) bool {
  133. if err = json.Unmarshal([]byte(value), &val); err != nil {
  134. log.Errorf("error %q while unparsing UUID for value: %v\n", err, value)
  135. }
  136. checks++ //Just to see how many checks we made, for statistical purposes
  137. if avatarKey == val.UUID {
  138. found = key
  139. return false
  140. }
  141. return true
  142. })
  143. return err
  144. })
  145. db.Close()
  146. case "leveldb":
  147. db, err := leveldb.OpenFile(goslConfig.dbNamePath, nil)
  148. checkErrPanic(err)
  149. iter := db.NewIterator(nil, nil)
  150. for iter.Next() {
  151. // Remember that the contents of the returned slice should not be modified, and
  152. // only valid until the next call to Next.
  153. key := iter.Key()
  154. value := iter.Value()
  155. if err = json.Unmarshal(value, &val); err != nil {
  156. log.Errorf("error %q while unparsing UUID for data: %v\n", err, value)
  157. continue // a bit insane, but at least we will skip a few broken records
  158. }
  159. checks++ //Just to see how many checks we made, for statistical purposes
  160. if avatarKey == val.UUID {
  161. found = string(key)
  162. break
  163. }
  164. }
  165. iter.Release()
  166. err = iter.Error()
  167. checkErr(err)
  168. db.Close()
  169. } // /switch
  170. log.Debugf("made %d checks for %q in %v\n", checks, avatarKey, time.Since(time_start))
  171. return found, val.Grid
  172. }
  173. */
  174. // Universal search, since we put everything in the KV database, we can basically search for anything.
  175. // *Way* more efficient! (gwyneth 20211031)
  176. func searchKV(searchItem string) (name string, uuid string, grid string) {
  177. var val = avatarUUID{"", uuid.Nil, ""}
  178. time_start := time.Now()
  179. var err error // to deal with scope issues
  180. switch goslConfig.database {
  181. case "badger":
  182. kv, err = badger.Open(Opt)
  183. checkErrPanic(err)
  184. defer kv.Close()
  185. err = kv.View(func(txn *badger.Txn) error {
  186. item, err := txn.Get([]byte(searchItem))
  187. if err != nil {
  188. return err
  189. }
  190. data, err := item.ValueCopy(nil)
  191. if err != nil {
  192. log.Errorf("error %q while getting data from %v\n", err, item)
  193. return err
  194. }
  195. if err = json.Unmarshal(data, &val); err != nil {
  196. log.Errorf("error while unparsing UUID for name: %q (%v)\n", searchItem, err)
  197. return err
  198. }
  199. return nil
  200. })
  201. case "buntdb":
  202. db, err := buntdb.Open(goslConfig.dbNamePath)
  203. checkErrPanic(err)
  204. defer db.Close()
  205. var data string
  206. err = db.View(func(tx *buntdb.Tx) error {
  207. data, err = tx.Get(searchItem)
  208. return err
  209. })
  210. err = json.Unmarshal([]byte(data), &val)
  211. if err != nil {
  212. log.Errorf("error while unparsing UUID for name: %q (%v)\n", searchItem, err)
  213. }
  214. case "leveldb":
  215. db, err := leveldb.OpenFile(goslConfig.dbNamePath, nil)
  216. checkErrPanic(err)
  217. defer db.Close()
  218. data, err := db.Get([]byte(searchItem), nil)
  219. if err != nil {
  220. log.Errorf("error while getting UUID for name: %q (%v)\n", searchItem, err)
  221. } else {
  222. if err = json.Unmarshal(data, &val); err != nil {
  223. log.Errorf("error while unparsing UUID for name: %q (%v)\n", searchItem, err)
  224. }
  225. }
  226. }
  227. log.Debugf("time to lookup %q: %v\n", searchItem, time.Since(time_start))
  228. if err != nil {
  229. checkErr(err)
  230. return "", uuid.Nil, ""
  231. } // else:
  232. return val.AvatarName, val.UUID, val.Grid
  233. }