| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | /* * EliasDB * * Copyright 2016 Matthias Ladkau. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. *//*Package view contains general page view constants and functions.PageView is the super-struct for all page views. A page view is special objectattached to a particular StorageFile record. A view provides specialisedfunctions for the record it is attached to.Use GetPageView() if the record has already view information stored on it orNewPageView() to initialise or reassign a given record.*/package viewimport (	"fmt"	"devt.de/krotik/eliasdb/storage/file")/*ViewPageHeader is the header magic number to identify view pages*/const ViewPageHeader = 0x1990/*OffsetNextPage is the offset for next page id*/const OffsetNextPage = file.SizeShort/*OffsetPrevPage is the offset for previous page id*/const OffsetPrevPage = OffsetNextPage + file.SizeLong/*OffsetData is the offset for page specific data*/const OffsetData = OffsetPrevPage + file.SizeLong/*PageView data structure*/type PageView struct {	Record *file.Record // Record which is wrapped by the PageView}/*GetPageView returns the page view of a given record.*/func GetPageView(record *file.Record) *PageView {	rpv := record.PageView()	pv, ok := rpv.(*PageView)	if ok {		return pv	}	pv = &PageView{record}	pv.checkMagic()	record.SetPageView(pv)	return pv}/*NewPageView creates a new page view for a given record.*/func NewPageView(record *file.Record, pagetype int16) *PageView {	pv := &PageView{record}	record.SetPageView(pv)	pv.SetType(pagetype)	return pv}/*Type gets the type of this page view which is stored on the record.*/func (pv *PageView) Type() int16 {	return pv.Record.ReadInt16(0) - ViewPageHeader}/*SetType sets the type of this page view which is stored on the record.*/func (pv *PageView) SetType(pagetype int16) {	pv.Record.WriteInt16(0, ViewPageHeader+pagetype)}/*checkMagic checks if the magic number at the beginning of the wrapped recordis valid.*/func (pv *PageView) checkMagic() bool {	magic := pv.Record.ReadInt16(0)	if magic >= ViewPageHeader &&		magic <= ViewPageHeader+TypeFreePhysicalSlotPage {		return true	}	panic("Unexpected header found in PageView")}/*NextPage returns the id of the next page.*/func (pv *PageView) NextPage() uint64 {	pv.checkMagic()	return pv.Record.ReadUInt64(OffsetNextPage)}/*SetNextPage sets the id of the next page.*/func (pv *PageView) SetNextPage(val uint64) {	pv.checkMagic()	pv.Record.WriteUInt64(OffsetNextPage, val)}/*PrevPage returns the id of the previous page.*/func (pv *PageView) PrevPage() uint64 {	pv.checkMagic()	return pv.Record.ReadUInt64(OffsetPrevPage)}/*SetPrevPage sets the id of the previous page.*/func (pv *PageView) SetPrevPage(val uint64) {	pv.checkMagic()	pv.Record.WriteUInt64(OffsetPrevPage, val)}func (pv *PageView) String() string {	return fmt.Sprintf("PageView: %v (type:%v previous page:%v next page:%v)",		pv.Record.ID(), pv.Type(), pv.PrevPage(), pv.NextPage())}
 |