func (self *ClusterConfiguration) getShardRange(querySpec QuerySpec, shards []*ShardData) []*ShardData { if querySpec.AllShardsQuery() { return shards } startTime := common.TimeToMicroseconds(querySpec.GetStartTime()) endTime := common.TimeToMicroseconds(querySpec.GetEndTime()) // the shards are always in descending order, if we have the following shards // [t + 20, t + 30], [t + 10, t + 20], [t, t + 10] // if we are querying [t + 5, t + 15], we have to find the first shard whose // startMicro is less than the end time of the query, // which is the second shard [t + 10, t + 20], then // start searching from this shard for the shard that has // endMicro less than the start time of the query, which is // no entry (sort.Search will return the length of the slice // in this case) so we return [t + 10, t + 20], [t, t + 10] // as expected startIndex := sort.Search(len(shards), func(n int) bool { return shards[n].startMicro < endTime }) if startIndex == len(shards) { return nil } endIndex := sort.Search(len(shards)-startIndex, func(n int) bool { return shards[n+startIndex].endMicro <= startTime }) return shards[startIndex : endIndex+startIndex] }
func NewShard(id uint32, startTime, endTime time.Time, database, spaceName string, wal WAL) *ShardData { shardDuration := endTime.Sub(startTime) return &ShardData{ id: id, startTime: startTime, endTime: endTime, wal: wal, startMicro: common.TimeToMicroseconds(startTime), endMicro: common.TimeToMicroseconds(endTime), serverIds: make([]uint32, 0), shardDuration: shardDuration, shardNanoseconds: uint64(shardDuration), SpaceName: spaceName, Database: database, } }
func (self *Shard) getIterators(fields []*metastore.Field, start, end time.Time, isAscendingQuery bool) (iterators []storage.Iterator) { iterators = make([]storage.Iterator, len(fields)) // start the iterators to go through the series data for i, field := range fields { iterators[i] = self.db.Iterator() t := start var seq uint64 = 0 if !isAscendingQuery { t = end seq = maxSeqNumber } tmicro := common.TimeToMicroseconds(t) sk := newStorageKey(field.Id, tmicro, seq) log.Debug("Initializing iterator to %v", sk.bytes()) iterators[i].Seek(sk.bytes()) if !isAscendingQuery && iterators[i].Valid() { iterators[i].Prev() } if err := iterators[i].Error(); err != nil { log.Error("Error while getting iterators: %s", err) return nil } } return }
func (self *Shard) executeSinglePointQuery(querySpec *parser.QuerySpec, name string, columns []string, p engine.Processor) error { fields, err := self.getFieldsForSeries(querySpec.Database(), name, columns) if err != nil { log.Error("Error looking up fields for %s: %s", name, err) return err } query := querySpec.SelectQuery() fieldCount := len(fields) fieldNames := make([]string, 0, fieldCount) point := &protocol.Point{Values: make([]*protocol.FieldValue, 0, fieldCount)} timestamp := common.TimeToMicroseconds(query.GetStartTime()) sequenceNumber, err := query.GetSinglePointQuerySequenceNumber() if err != nil { return err } // set the timestamp and sequence number point.SequenceNumber = &sequenceNumber point.SetTimestampInMicroseconds(timestamp) for _, field := range fields { sk := newStorageKey(field.Id, timestamp, sequenceNumber) data, err := self.db.Get(sk.bytes()) if err != nil { return err } if data == nil { continue } fieldValue := &protocol.FieldValue{} err = proto.Unmarshal(data, fieldValue) if err != nil { return err } fieldNames = append(fieldNames, field.Name) point.Values = append(point.Values, fieldValue) } result := &protocol.Series{Name: &name, Fields: fieldNames, Points: []*protocol.Point{point}} if len(result.Points) > 0 { _, err := p.Yield(result) return err } return nil }
func (self *Shard) fetchSinglePoint(querySpec *parser.QuerySpec, series string, fields []*metastore.Field) (*protocol.Series, error) { query := querySpec.SelectQuery() fieldCount := len(fields) fieldNames := make([]string, 0, fieldCount) point := &protocol.Point{Values: make([]*protocol.FieldValue, 0, fieldCount)} timestamp := common.TimeToMicroseconds(query.GetStartTime()) sequenceNumber, err := query.GetSinglePointQuerySequenceNumber() if err != nil { return nil, err } timeAndSequenceBuffer := bytes.NewBuffer(make([]byte, 0, 16)) binary.Write(timeAndSequenceBuffer, binary.BigEndian, self.convertTimestampToUint(×tamp)) binary.Write(timeAndSequenceBuffer, binary.BigEndian, sequenceNumber) sequenceNumber_uint64 := uint64(sequenceNumber) point.SequenceNumber = &sequenceNumber_uint64 point.SetTimestampInMicroseconds(timestamp) timeAndSequenceBytes := timeAndSequenceBuffer.Bytes() for _, field := range fields { pointKeyBuff := bytes.NewBuffer(make([]byte, 0, 24)) pointKeyBuff.Write(field.IdAsBytes()) pointKeyBuff.Write(timeAndSequenceBytes) if data, err := self.db.Get(pointKeyBuff.Bytes()); err != nil { return nil, err } else { fieldValue := &protocol.FieldValue{} err := proto.Unmarshal(data, fieldValue) if err != nil { return nil, err } if data != nil { fieldNames = append(fieldNames, field.Name) point.Values = append(point.Values, fieldValue) } } } result := &protocol.Series{Name: &series, Fields: fieldNames, Points: []*protocol.Point{point}} return result, nil }
func (self *Shard) deleteRangeOfSeries(database, series string, startTime, endTime time.Time) error { fields := self.metaStore.GetFieldsForSeries(database, series) st := common.TimeToMicroseconds(startTime) et := common.TimeToMicroseconds(endTime) return self.deleteRangeOfFields(fields, st, et) }
func (self *Shard) byteArrayForTime(t time.Time) []byte { timeBuffer := bytes.NewBuffer(make([]byte, 0, 8)) timeMicro := common.TimeToMicroseconds(t) binary.Write(timeBuffer, binary.BigEndian, self.convertTimestampToUint(&timeMicro)) return timeBuffer.Bytes() }
func (self *Shard) deleteRangeOfSeries(database, series string, startTime, endTime time.Time) error { startTimeBytes, endTimeBytes := self.byteArraysForStartAndEndTimes(common.TimeToMicroseconds(startTime), common.TimeToMicroseconds(endTime)) return self.deleteRangeOfSeriesCommon(database, series, startTimeBytes, endTimeBytes) }