package atree import ( "errors" "os" "sync" ) const ( filePerm = 0666 ) type PeriodsWriter interface { Feed(uint32, float64) FeedNoSend(uint32, float64) Close() error } type WorkerMeasureConsumer interface { FeedNoSend(uint32, float64) } type AtreeMeasureConsumer interface { Feed(uint32, float64) } // type _page struct { PageNo uint32 Buf []byte ReferenceCount int } type Atree struct { indexFile *os.File dataFile *os.File mutex sync.Mutex pages map[uint32]*_page pageWaits map[uint32][]chan readResult pagesToRead []uint32 readSignalCh chan struct{} } type Options struct { IndexFile *os.File DataFile *os.File } func New(opt Options) (*Atree, error) { if opt.IndexFile == nil { return nil, errors.New("IndexFile option is required") } if opt.DataFile == nil { return nil, errors.New("DataFile option is required") } s := &Atree{ indexFile: opt.IndexFile, dataFile: opt.DataFile, pages: make(map[uint32]*_page), pageWaits: make(map[uint32][]chan readResult), readSignalCh: make(chan struct{}, 1), } return s, nil } func (s *Atree) Run() { //go s.pageWriter() go s.pageReader() } // FIND func (s *Atree) findDataPage(rootPageNo uint32, timestamp uint32) (uint32, []byte, error) { // indexPageNo := rootPageNo // for { // buf, err := s.fetchIndexPage(indexPageNo) // if err != nil { // return 0, nil, fmt.Errorf("fetchIndexPage(%d): %s", indexPageNo, err) // } // foundPageNo := findPageNo(buf, timestamp) // s.releasePage(indexPageNo) // // fix // if buf[isLastLevelIdx] == 1 { // buf, err := s.fetchDataPage(foundPageNo) // if err != nil { // return 0, nil, fmt.Errorf("fetchDataPage(%d): %s", foundPageNo, err) // } // return foundPageNo, buf, nil // } // // вглубь // indexPageNo = foundPageNo // } return 0, nil, nil } type PathLeg struct { PageNo uint32 Data []byte } type PathToDataPage struct { Legs []PathLeg LastPageNo uint32 } func (s *Atree) FindPathToLastPage(rootPageNo uint32) (_ PathToDataPage, err error) { // var ( // pageNo = rootPageNo // legs []PathLeg // ) // for { // var buf []byte // buf, err = s.fetchIndexPage(pageNo) // if err != nil { // err = fmt.Errorf("FetchIndexPage(%d): %s", pageNo, err) // return // } // legs = append(legs, PathLeg{ // PageNo: pageNo, // Data: buf, // // childIdx не нужен // }) // foundPageNo := getLastPageNo(buf) // // fix // if buf[isLastLevelIdx] == 1 { // return PathToDataPage{ // Legs: legs, // LastPageNo: foundPageNo, // }, nil // } // // вглубь // pageNo = foundPageNo // } return } // DELETE type Level struct { PageNo uint32 PageData []byte Idx int ChildQty int } func (s *Atree) GetAllPages(rootPageNo uint32) (_ []uint32, err error) { // var ( // pageNumbers []uint32 // levels []*Level // ) // buf, err := s.fetchIndexPage(rootPageNo) // if err != nil { // return nil, fmt.Errorf("fetchIndexPage(%d): %s", rootPageNo, err) // } // pageNumbers = append(pageNumbers, rootPageNo) // // if buf[isDataPageNumbersIdx] == 1 { // // pageNumbers := listPageNumbers(buf) // // dataPages = append(dataPages, pageNumbers...) // // s.releasePage(rootPageNo) // // return PageLists{ // // DataPages: dataPages, // // IndexPages: indexPages, // // }, nil // // } // childQty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:]) // levels = append(levels, &Level{ // PageNo: rootPageNo, // PageData: buf, // Idx: 0, // ChildQty: int(childQty), // }) // for { // if len(levels) == 0 { // return pageNumbers, nil // } // lastIdx := len(levels) - 1 // level := levels[lastIdx] // if level.Idx < level.ChildQty { // pageNo := getPageNo(level.PageData, level.Idx) // level.Idx++ // var buf []byte // buf, err = s.fetchPage(pageNo) // if err != nil { // return nil, fmt.Errorf("fetchPage(%d): %s", pageNo, err) // } // pageNumbers = append(pageNumbers, pageNo) // if buf[pageTypeIdx] == PageTypeData { // //pageNumbers := listPageNumbers(buf) // //dataPages = append(dataPages, pageNumbers...) // s.releasePage(pageNo) // } else { // childQty, _ = bin.GetUint16(buf[indexRecordsQtyIdx:]) // levels = append(levels, &Level{ // PageNo: pageNo, // PageData: buf, // Idx: 0, // ChildQty: int(childQty), // }) // } // } else { // s.releasePage(level.PageNo) // levels = levels[:lastIdx] // } // } return }