leveldb.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at http://mozilla.org/MPL/2.0/.
  6. //go:generate -command genxdr go run ../../vendor/github.com/calmh/xdr/cmd/genxdr/main.go
  7. //go:generate genxdr -o leveldb_xdr.go leveldb.go
  8. package db
  9. import (
  10. "bytes"
  11. "fmt"
  12. "github.com/syncthing/syncthing/lib/protocol"
  13. "github.com/syncthing/syncthing/lib/sync"
  14. "github.com/syndtr/goleveldb/leveldb"
  15. "github.com/syndtr/goleveldb/leveldb/opt"
  16. )
  17. var (
  18. clockTick int64
  19. clockMut = sync.NewMutex()
  20. )
  21. func clock(v int64) int64 {
  22. clockMut.Lock()
  23. defer clockMut.Unlock()
  24. if v > clockTick {
  25. clockTick = v + 1
  26. } else {
  27. clockTick++
  28. }
  29. return clockTick
  30. }
  31. const (
  32. KeyTypeDevice = iota
  33. KeyTypeGlobal
  34. KeyTypeBlock
  35. KeyTypeDeviceStatistic
  36. KeyTypeFolderStatistic
  37. KeyTypeVirtualMtime
  38. KeyTypeFolderIdx
  39. KeyTypeDeviceIdx
  40. )
  41. type fileVersion struct {
  42. version protocol.Vector
  43. device []byte
  44. }
  45. type versionList struct {
  46. versions []fileVersion
  47. }
  48. func (l versionList) String() string {
  49. var b bytes.Buffer
  50. var id protocol.DeviceID
  51. b.WriteString("{")
  52. for i, v := range l.versions {
  53. if i > 0 {
  54. b.WriteString(", ")
  55. }
  56. copy(id[:], v.device)
  57. fmt.Fprintf(&b, "{%d, %v}", v.version, id)
  58. }
  59. b.WriteString("}")
  60. return b.String()
  61. }
  62. type fileList []protocol.FileInfo
  63. func (l fileList) Len() int {
  64. return len(l)
  65. }
  66. func (l fileList) Swap(a, b int) {
  67. l[a], l[b] = l[b], l[a]
  68. }
  69. func (l fileList) Less(a, b int) bool {
  70. return l[a].Name < l[b].Name
  71. }
  72. type dbReader interface {
  73. Get([]byte, *opt.ReadOptions) ([]byte, error)
  74. }
  75. // Flush batches to disk when they contain this many records.
  76. const batchFlushSize = 64
  77. func getFile(db dbReader, key []byte) (protocol.FileInfo, bool) {
  78. bs, err := db.Get(key, nil)
  79. if err == leveldb.ErrNotFound {
  80. return protocol.FileInfo{}, false
  81. }
  82. if err != nil {
  83. panic(err)
  84. }
  85. var f protocol.FileInfo
  86. err = f.UnmarshalXDR(bs)
  87. if err != nil {
  88. panic(err)
  89. }
  90. return f, true
  91. }