pageview.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. /*
  11. Package view contains general page view constants and functions.
  12. PageView is the super-struct for all page views. A page view is special object
  13. attached to a particular StorageFile record. A view provides specialised
  14. functions for the record it is attached to.
  15. Use GetPageView() if the record has already view information stored on it or
  16. NewPageView() to initialise or reassign a given record.
  17. */
  18. package view
  19. import (
  20. "fmt"
  21. "devt.de/krotik/eliasdb/storage/file"
  22. )
  23. /*
  24. ViewPageHeader is the header magic number to identify view pages
  25. */
  26. const ViewPageHeader = 0x1990
  27. /*
  28. OffsetNextPage is the offset for next page id
  29. */
  30. const OffsetNextPage = file.SizeShort
  31. /*
  32. OffsetPrevPage is the offset for previous page id
  33. */
  34. const OffsetPrevPage = OffsetNextPage + file.SizeLong
  35. /*
  36. OffsetData is the offset for page specific data
  37. */
  38. const OffsetData = OffsetPrevPage + file.SizeLong
  39. /*
  40. PageView data structure
  41. */
  42. type PageView struct {
  43. Record *file.Record // Record which is wrapped by the PageView
  44. }
  45. /*
  46. GetPageView returns the page view of a given record.
  47. */
  48. func GetPageView(record *file.Record) *PageView {
  49. rpv := record.PageView()
  50. pv, ok := rpv.(*PageView)
  51. if ok {
  52. return pv
  53. }
  54. pv = &PageView{record}
  55. pv.checkMagic()
  56. record.SetPageView(pv)
  57. return pv
  58. }
  59. /*
  60. NewPageView creates a new page view for a given record.
  61. */
  62. func NewPageView(record *file.Record, pagetype int16) *PageView {
  63. pv := &PageView{record}
  64. record.SetPageView(pv)
  65. pv.SetType(pagetype)
  66. return pv
  67. }
  68. /*
  69. Type gets the type of this page view which is stored on the record.
  70. */
  71. func (pv *PageView) Type() int16 {
  72. return pv.Record.ReadInt16(0) - ViewPageHeader
  73. }
  74. /*
  75. SetType sets the type of this page view which is stored on the record.
  76. */
  77. func (pv *PageView) SetType(pagetype int16) {
  78. pv.Record.WriteInt16(0, ViewPageHeader+pagetype)
  79. }
  80. /*
  81. checkMagic checks if the magic number at the beginning of the wrapped record
  82. is valid.
  83. */
  84. func (pv *PageView) checkMagic() bool {
  85. magic := pv.Record.ReadInt16(0)
  86. if magic >= ViewPageHeader &&
  87. magic <= ViewPageHeader+TypeFreePhysicalSlotPage {
  88. return true
  89. }
  90. panic("Unexpected header found in PageView")
  91. }
  92. /*
  93. NextPage returns the id of the next page.
  94. */
  95. func (pv *PageView) NextPage() uint64 {
  96. pv.checkMagic()
  97. return pv.Record.ReadUInt64(OffsetNextPage)
  98. }
  99. /*
  100. SetNextPage sets the id of the next page.
  101. */
  102. func (pv *PageView) SetNextPage(val uint64) {
  103. pv.checkMagic()
  104. pv.Record.WriteUInt64(OffsetNextPage, val)
  105. }
  106. /*
  107. PrevPage returns the id of the previous page.
  108. */
  109. func (pv *PageView) PrevPage() uint64 {
  110. pv.checkMagic()
  111. return pv.Record.ReadUInt64(OffsetPrevPage)
  112. }
  113. /*
  114. SetPrevPage sets the id of the previous page.
  115. */
  116. func (pv *PageView) SetPrevPage(val uint64) {
  117. pv.checkMagic()
  118. pv.Record.WriteUInt64(OffsetPrevPage, val)
  119. }
  120. func (pv *PageView) String() string {
  121. return fmt.Sprintf("PageView: %v (type:%v previous page:%v next page:%v)",
  122. pv.Record.ID(), pv.Type(), pv.PrevPage(), pv.NextPage())
  123. }