lowlevel.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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 https://mozilla.org/MPL/2.0/.
  6. package olddb
  7. import (
  8. "encoding/binary"
  9. "time"
  10. "github.com/syncthing/syncthing/internal/db/olddb/backend"
  11. )
  12. // deprecatedLowlevel is the lowest level database interface. It has a very simple
  13. // purpose: hold the actual backend database, and the in-memory state
  14. // that belong to that database. In the same way that a single on disk
  15. // database can only be opened once, there should be only one deprecatedLowlevel for
  16. // any given backend.
  17. type deprecatedLowlevel struct {
  18. backend.Backend
  19. folderIdx *smallIndex
  20. deviceIdx *smallIndex
  21. keyer keyer
  22. }
  23. func NewLowlevel(backend backend.Backend) (*deprecatedLowlevel, error) {
  24. // Only log restarts in debug mode.
  25. db := &deprecatedLowlevel{
  26. Backend: backend,
  27. folderIdx: newSmallIndex(backend, []byte{KeyTypeFolderIdx}),
  28. deviceIdx: newSmallIndex(backend, []byte{KeyTypeDeviceIdx}),
  29. }
  30. db.keyer = newDefaultKeyer(db.folderIdx, db.deviceIdx)
  31. return db, nil
  32. }
  33. // ListFolders returns the list of folders currently in the database
  34. func (db *deprecatedLowlevel) ListFolders() []string {
  35. return db.folderIdx.Values()
  36. }
  37. func (db *deprecatedLowlevel) IterateMtimes(fn func(folder, name string, ondisk, virtual time.Time) error) error {
  38. it, err := db.NewPrefixIterator([]byte{KeyTypeVirtualMtime})
  39. if err != nil {
  40. return err
  41. }
  42. defer it.Release()
  43. for it.Next() {
  44. key := it.Key()[1:]
  45. folderID, ok := db.folderIdx.Val(binary.BigEndian.Uint32(key))
  46. if !ok {
  47. continue
  48. }
  49. name := key[4:]
  50. val := it.Value()
  51. var ondisk, virtual time.Time
  52. if err := ondisk.UnmarshalBinary(val[:len(val)/2]); err != nil {
  53. continue
  54. }
  55. if err := virtual.UnmarshalBinary(val[len(val)/2:]); err != nil {
  56. continue
  57. }
  58. if err := fn(string(folderID), string(name), ondisk, virtual); err != nil {
  59. return err
  60. }
  61. }
  62. return it.Error()
  63. }