if len(s.hotBuf) == cap(s.hotBuf) hotBuf中的v数量达到了500
flush操作
func(s *summary)asyncFlush(now time.Time){
s.mtx.Lock()
s.swapBufs(now)// Unblock the original goroutine that was responsible for the mutation// that triggered the compaction. But hold onto the global non-buffer// state mutex until the operation finishes.gofunc(){
s.flushColdBuf()
s.mtx.Unlock()}()}
swapBufs 交换 s.hotBuf, s.coldBuf
// swapBufs needs mtx AND bufMtx locked, coldBuf must be empty.func(s *summary)swapBufs(now time.Time){iflen(s.coldBuf)!=0{panic("coldBuf is not empty")}
s.hotBuf, s.coldBuf = s.coldBuf, s.hotBuf
// hotBuf is now empty and gets new expiration set.for now.After(s.hotBufExpTime){
s.hotBufExpTime = s.hotBufExpTime.Add(s.streamDuration)}}
func(s *Stream)Query(q float64)float64{if!s.flushed(){// Fast path when there hasn't been enough data for a flush;// this also yields better accuracy for small sets of data.
l :=len(s.b)if l ==0{return0}
i :=int(math.Ceil(float64(l)* q))if i >0{
i -=1}
s.maybeSort()return s.b[i].Value
}
s.flush()return s.stream.query(q)}