1st
This commit is contained in:
129
atree/select.go
Normal file
129
atree/select.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package atree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
diploma "gordenko.dev/dima/qb"
|
||||
)
|
||||
|
||||
type ContinueFullScanReq struct {
|
||||
FracDigits byte
|
||||
ResponseWriter AtreeMeasureConsumer
|
||||
LastPageNo uint32
|
||||
}
|
||||
|
||||
func (s *Atree) ContinueFullScan(req ContinueFullScanReq) error {
|
||||
buf, err := s.fetchDataPage(req.LastPageNo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fetchDataPage(%d): %s", req.LastPageNo, err)
|
||||
}
|
||||
|
||||
treeCursor, err := NewBackwardCursor(BackwardCursorOptions{
|
||||
PageNo: req.LastPageNo,
|
||||
PageData: buf,
|
||||
Atree: s,
|
||||
FracDigits: req.FracDigits,
|
||||
MetricType: diploma.Instant,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer treeCursor.Close()
|
||||
|
||||
for {
|
||||
timestamp, value, done, err := treeCursor.Prev()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
return nil
|
||||
}
|
||||
req.ResponseWriter.Feed(timestamp, value)
|
||||
}
|
||||
}
|
||||
|
||||
type ContinueRangeScanReq struct {
|
||||
FracDigits byte
|
||||
ResponseWriter AtreeMeasureConsumer
|
||||
LastPageNo uint32
|
||||
Since uint32
|
||||
}
|
||||
|
||||
func (s *Atree) ContinueRangeScan(req ContinueRangeScanReq) error {
|
||||
buf, err := s.fetchDataPage(req.LastPageNo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fetchDataPage(%d): %s", req.LastPageNo, err)
|
||||
}
|
||||
|
||||
treeCursor, err := NewBackwardCursor(BackwardCursorOptions{
|
||||
PageNo: req.LastPageNo,
|
||||
PageData: buf,
|
||||
Atree: s,
|
||||
FracDigits: req.FracDigits,
|
||||
MetricType: diploma.Instant,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer treeCursor.Close()
|
||||
|
||||
for {
|
||||
timestamp, value, done, err := treeCursor.Prev()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
return nil
|
||||
}
|
||||
req.ResponseWriter.Feed(timestamp, value)
|
||||
if timestamp < req.Since {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type RangeScanReq struct {
|
||||
FracDigits byte
|
||||
ResponseWriter AtreeMeasureConsumer
|
||||
RootPageNo uint32
|
||||
Since uint32
|
||||
Until uint32
|
||||
}
|
||||
|
||||
func (s *Atree) RangeScan(req RangeScanReq) error {
|
||||
pageNo, buf, err := s.findDataPage(req.RootPageNo, req.Until)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cursor, err := NewBackwardCursor(BackwardCursorOptions{
|
||||
PageNo: pageNo,
|
||||
PageData: buf,
|
||||
Atree: s,
|
||||
FracDigits: req.FracDigits,
|
||||
MetricType: diploma.Instant,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cursor.Close()
|
||||
|
||||
for {
|
||||
timestamp, value, done, err := cursor.Prev()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
return nil
|
||||
}
|
||||
|
||||
if timestamp <= req.Until {
|
||||
req.ResponseWriter.Feed(timestamp, value)
|
||||
|
||||
if timestamp < req.Since {
|
||||
// - записи, удовлетворяющие временным рамкам, закончились.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user