freezer_meta.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2022 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package rawdb
  17. import (
  18. "io"
  19. "os"
  20. "github.com/ethereum/go-ethereum/log"
  21. "github.com/ethereum/go-ethereum/rlp"
  22. )
  23. const freezerVersion = 1 // The initial version tag of freezer table metadata
  24. // freezerTableMeta wraps all the metadata of the freezer table.
  25. type freezerTableMeta struct {
  26. // Version is the versioning descriptor of the freezer table.
  27. Version uint16
  28. // VirtualTail indicates how many items have been marked as deleted.
  29. // Its value is equal to the number of items removed from the table
  30. // plus the number of items hidden in the table, so it should never
  31. // be lower than the "actual tail".
  32. VirtualTail uint64
  33. }
  34. // newMetadata initializes the metadata object with the given virtual tail.
  35. func newMetadata(tail uint64) *freezerTableMeta {
  36. return &freezerTableMeta{
  37. Version: freezerVersion,
  38. VirtualTail: tail,
  39. }
  40. }
  41. // readMetadata reads the metadata of the freezer table from the
  42. // given metadata file.
  43. func readMetadata(file *os.File) (*freezerTableMeta, error) {
  44. _, err := file.Seek(0, io.SeekStart)
  45. if err != nil {
  46. return nil, err
  47. }
  48. var meta freezerTableMeta
  49. if err := rlp.Decode(file, &meta); err != nil {
  50. return nil, err
  51. }
  52. return &meta, nil
  53. }
  54. // writeMetadata writes the metadata of the freezer table into the
  55. // given metadata file.
  56. func writeMetadata(file *os.File, meta *freezerTableMeta) error {
  57. _, err := file.Seek(0, io.SeekStart)
  58. if err != nil {
  59. return err
  60. }
  61. return rlp.Encode(file, meta)
  62. }
  63. // loadMetadata loads the metadata from the given metadata file.
  64. // Initializes the metadata file with the given "actual tail" if
  65. // it's empty.
  66. func loadMetadata(file *os.File, tail uint64) (*freezerTableMeta, error) {
  67. stat, err := file.Stat()
  68. if err != nil {
  69. return nil, err
  70. }
  71. // Write the metadata with the given actual tail into metadata file
  72. // if it's non-existent. There are two possible scenarios here:
  73. // - the freezer table is empty
  74. // - the freezer table is legacy
  75. // In both cases, write the meta into the file with the actual tail
  76. // as the virtual tail.
  77. if stat.Size() == 0 {
  78. m := newMetadata(tail)
  79. if err := writeMetadata(file, m); err != nil {
  80. return nil, err
  81. }
  82. return m, nil
  83. }
  84. m, err := readMetadata(file)
  85. if err != nil {
  86. return nil, err
  87. }
  88. // Update the virtual tail with the given actual tail if it's even
  89. // lower than it. Theoretically it shouldn't happen at all, print
  90. // a warning here.
  91. if m.VirtualTail < tail {
  92. log.Warn("Updated virtual tail", "have", m.VirtualTail, "now", tail)
  93. m.VirtualTail = tail
  94. if err := writeMetadata(file, m); err != nil {
  95. return nil, err
  96. }
  97. }
  98. return m, nil
  99. }