pagedstoragefileheader.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package paging
  11. import "devt.de/krotik/eliasdb/storage/file"
  12. /*
  13. PageHeader is the magic number to identify page headers
  14. */
  15. const PageHeader = 0x1980
  16. /*
  17. TotalLists is the number of lists which can be stored in this header
  18. */
  19. const TotalLists = 5
  20. /*
  21. OffsetLists is the offset for list entries in this header
  22. */
  23. const OffsetLists = 2
  24. /*
  25. OffsetRoots is the number of lists which can be stored in this header
  26. */
  27. const OffsetRoots = OffsetLists + (2 * TotalLists * file.SizeLong)
  28. /*
  29. PagedStorageFileHeader data structure
  30. */
  31. type PagedStorageFileHeader struct {
  32. record *file.Record // Record which is being used for the header information
  33. totalRoots int // Number of root values which can be stored
  34. }
  35. /*
  36. NewPagedStorageFileHeader creates a new NewPagedStorageFileHeader.
  37. */
  38. func NewPagedStorageFileHeader(record *file.Record, isnew bool) *PagedStorageFileHeader {
  39. totalRoots := (len(record.Data()) - OffsetRoots) / file.SizeLong
  40. if totalRoots < 1 {
  41. panic("Cannot store any roots - record is too small")
  42. }
  43. ret := &PagedStorageFileHeader{record, totalRoots}
  44. if isnew {
  45. record.WriteUInt16(0, PageHeader)
  46. } else {
  47. ret.CheckMagic()
  48. }
  49. return ret
  50. }
  51. /*
  52. CheckMagic checks the header magic value of this header.
  53. */
  54. func (psfh *PagedStorageFileHeader) CheckMagic() {
  55. if psfh.record.ReadUInt16(0) != PageHeader {
  56. panic("Unexpected header found in PagedStorageFileHeader")
  57. }
  58. }
  59. /*
  60. Roots returns the number of possible root values which can be set.
  61. */
  62. func (psfh *PagedStorageFileHeader) Roots() int {
  63. return psfh.totalRoots
  64. }
  65. /*
  66. Root returns a root value.
  67. */
  68. func (psfh *PagedStorageFileHeader) Root(root int) uint64 {
  69. return psfh.record.ReadUInt64(offsetRoot(root))
  70. }
  71. /*
  72. SetRoot sets a root value.
  73. */
  74. func (psfh *PagedStorageFileHeader) SetRoot(root int, val uint64) {
  75. psfh.record.WriteUInt64(offsetRoot(root), val)
  76. }
  77. /*
  78. offsetRoot calculates the offset of a root in the header record.
  79. */
  80. func offsetRoot(root int) int {
  81. return OffsetRoots + root*file.SizeLong
  82. }
  83. /*
  84. FirstListElement returns the first element of a list.
  85. */
  86. func (psfh *PagedStorageFileHeader) FirstListElement(list int16) uint64 {
  87. return psfh.record.ReadUInt64(offsetFirstListElement(list))
  88. }
  89. /*
  90. SetFirstListElement sets the first element of a list.
  91. */
  92. func (psfh *PagedStorageFileHeader) SetFirstListElement(list int16, val uint64) {
  93. psfh.record.WriteUInt64(offsetFirstListElement(list), val)
  94. }
  95. /*
  96. LastListElement returns the last element of a list.
  97. */
  98. func (psfh *PagedStorageFileHeader) LastListElement(list int16) uint64 {
  99. return psfh.record.ReadUInt64(offsetLastListElement(list))
  100. }
  101. /*
  102. SetLastListElement sets the last element of a list.
  103. */
  104. func (psfh *PagedStorageFileHeader) SetLastListElement(list int16, val uint64) {
  105. psfh.record.WriteUInt64(offsetLastListElement(list), val)
  106. }
  107. /*
  108. offsetFirstListElement returns offset of the first element of a list.
  109. */
  110. func offsetFirstListElement(list int16) int {
  111. return OffsetLists + 2*file.SizeLong*int(list)
  112. }
  113. /*
  114. offsetLastListElement returns offset of the last element of a list.
  115. */
  116. func offsetLastListElement(list int16) int {
  117. return offsetFirstListElement(list) + file.SizeLong
  118. }