2017-04-11 02:59:45 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Copyright 2017 The Prometheus Authors
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// you may not use this file except in compliance with the License.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// You may obtain a copy of the License at
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// http://www.apache.org/licenses/LICENSE-2.0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Unless required by applicable law or agreed to in writing, software
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// See the License for the specific language governing permissions and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// limitations under the License.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								package index
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								import (
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-20 14:58:19 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"bufio"
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"encoding/binary"
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"fmt"
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-16 07:24:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"hash"
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"hash/crc32"
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"io"
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-09 21:21:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"math"
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-23 17:50:22 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"os"
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"path/filepath"
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"sort"
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-12 18:38:43 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"strings"
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-20 20:10:37 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/pkg/errors"
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/tsdb/chunks"
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-09 21:21:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/tsdb/fileutil"
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-04 17:27:26 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									"github.com/prometheus/tsdb/labels"
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// MagicIndex 4 bytes at the head of an index file.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									MagicIndex = 0xBAAAD700
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									indexFormatV1 = 1
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									indexFormatV2 = 2
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-23 17:50:22 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type indexWriterSeries struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									labels labels.Labels
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									chunks []chunks.Meta // series file offset of chunks
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									offset uint32        // index file offset of series reference
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type indexWriterSeriesSlice []*indexWriterSeries
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s indexWriterSeriesSlice) Len() int      { return len(s) }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s indexWriterSeriesSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s indexWriterSeriesSlice) Less(i, j int) bool {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return labels.Compare(s[i].labels, s[j].labels) < 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type indexWriterStage uint8
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const (
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									idxStageNone indexWriterStage = iota
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									idxStageSymbols
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									idxStageSeries
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									idxStageLabelIndex
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									idxStagePostings
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									idxStageDone
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s indexWriterStage) String() string {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch s {
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageNone:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "none"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageSymbols:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "symbols"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageSeries:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "series"
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageLabelIndex:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "label index"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStagePostings:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "postings"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageDone:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "done"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return "<unknown>"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// The table gets initialized with sync.Once but may still cause a race
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// with any other use of the crc32 package anywhere. Thus we initialize it
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// before.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								var castagnoliTable *crc32.Table
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func init() {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									castagnoliTable = crc32.MakeTable(crc32.Castagnoli)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// newCRC32 initializes a CRC32 hash with a preconfigured polynomial, so the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// polynomial may be easily changed in one location at a later time, if necessary.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func newCRC32() hash.Hash32 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return crc32.New(castagnoliTable)
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Writer implements the IndexWriter interface for the standard
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// serialization format.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type Writer struct {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									f    *os.File
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									fbuf *bufio.Writer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									pos  uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									toc   indexTOC
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									stage indexWriterStage
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Reusable memory.
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									buf1    encbuf
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									buf2    encbuf
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32s []uint32
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									symbols       map[string]uint32 // symbol offsets
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-04 22:08:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									seriesOffsets map[uint64]uint64 // offsets of series
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									labelIndexes  []hashEntry       // label index offsets
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									postings      []hashEntry       // postings lists offsets
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Hold last series to validate that clients insert new series in order.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									lastSeries labels.Labels
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-16 07:24:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									crc32 hash.Hash
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Version int
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type indexTOC struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									symbols           uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									series            uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									labelIndices      uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									labelIndicesTable uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									postings          uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									postingsTable     uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-12 18:40:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// NewWriter returns a new Writer to the given filename. It serializes data in format version 2.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func NewWriter(fn string) (*Writer, error) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dir := filepath.Dir(fn)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									df, err := fileutil.OpenDir(dir)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									defer df.Close() // Close for platform windows.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := os.RemoveAll(fn); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "remove any existing index at path")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-31 22:37:41 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									f, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, 0666)
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := fileutil.Fsync(df); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "sync dir")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iw := &Writer{
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										f:     f,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										fbuf:  bufio.NewWriterSize(f, 1<<22),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										pos:   0,
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										stage: idxStageNone,
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Reusable memory.
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										buf1:    encbuf{b: make([]byte, 0, 1<<22)},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										buf2:    encbuf{b: make([]byte, 0, 1<<22)},
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										uint32s: make([]uint32, 0, 1<<15),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Caches.
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										symbols:       make(map[string]uint32, 1<<13),
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-04 22:08:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										seriesOffsets: make(map[uint64]uint64, 1<<16),
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-27 00:04:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										crc32:         newCRC32(),
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := iw.writeMeta(); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return iw, nil
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) write(bufs ...[]byte) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, b := range bufs {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										n, err := w.fbuf.Write(b)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.pos += uint64(n)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-05 20:58:09 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										// For now the index file must not grow beyond 64GiB. Some of the fixed-sized
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// offset references in v1 are only 4 bytes large.
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// Once we move to compressed/varint representations in those areas, this limitation
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// can be lifted.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-05 20:58:09 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if w.pos > 16*math.MaxUint32 {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("exceeding max size of 64GiB")
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return nil
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// addPadding adds zero byte padding until the file size is a multiple size.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) addPadding(size int) error {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									p := w.pos % uint64(size)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if p == 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									p = uint64(size) - p
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return errors.Wrap(w.write(make([]byte, p)), "add padding")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// ensureStage handles transitions between write stages and ensures that IndexWriter
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// methods are called in an order valid for the implementation.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) ensureStage(s indexWriterStage) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if w.stage == s {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if w.stage > s {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Errorf("invalid stage %q, currently at %q", s, w.stage)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Mark start of sections in table of contents.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch s {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageSymbols:
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.toc.symbols = w.pos
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageSeries:
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.toc.series = w.pos
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageLabelIndex:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.toc.labelIndices = w.pos
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStagePostings:
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.toc.postings = w.pos
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case idxStageDone:
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.toc.labelIndicesTable = w.pos
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err := w.writeOffsetTable(w.labelIndexes); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.toc.postingsTable = w.pos
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err := w.writeOffsetTable(w.postings); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err := w.writeTOC(); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.stage = s
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-11 01:08:50 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) writeMeta() error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE32(MagicIndex)
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									w.buf1.putByte(indexFormatV2)
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return w.write(w.buf1.get())
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// AddSeries adds the series one at a time along with its chunks.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) AddSeries(ref uint64, lset labels.Labels, chunks ...chunks.Meta) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.ensureStage(idxStageSeries); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if labels.Compare(lset, w.lastSeries) <= 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Errorf("out-of-order series added with label set %q", lset)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if _, ok := w.seriesOffsets[ref]; ok {
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Errorf("series with reference %d already added", ref)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									// We add padding to 16 bytes to increase the addressable space we get through 4 byte
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// series references.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-05 20:58:09 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									w.addPadding(16)
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if w.pos%16 != 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Errorf("series write not 16-byte aligned at %d", w.pos)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-05 20:58:09 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									w.seriesOffsets[ref] = w.pos / 16
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.reset()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putUvarint(len(lset))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, l := range lset {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 12:37:57 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										// here we have an index for the symbol file if v2, otherwise it's an offset
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										index, ok := w.symbols[l.Name]
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !ok {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("symbol entry for %q does not exist", l.Name)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarint32(index)
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										index, ok = w.symbols[l.Value]
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !ok {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("symbol entry for %q does not exist", l.Value)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarint32(index)
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putUvarint(len(chunks))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-08 03:05:28 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if len(chunks) > 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										c := chunks[0]
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putVarint64(c.MinTime)
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-08 03:05:28 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarint64(uint64(c.MaxTime - c.MinTime))
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarint64(c.Ref)
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-08 03:05:28 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										t0 := c.MaxTime
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ref0 := int64(c.Ref)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for _, c := range chunks[1:] {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											w.buf2.putUvarint64(uint64(c.MinTime - t0))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											w.buf2.putUvarint64(uint64(c.MaxTime - c.MinTime))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											t0 = c.MaxTime
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											w.buf2.putVarint64(int64(c.Ref) - ref0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											ref0 = int64(c.Ref)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putUvarint(w.buf2.len())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putHash(w.crc32)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.write(w.buf1.get(), w.buf2.get()); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Wrap(err, "write series data")
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.lastSeries = append(w.lastSeries[:0], lset...)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return nil
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) AddSymbols(sym map[string]struct{}) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.ensureStage(idxStageSymbols); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Generate sorted list of strings we will store as reference table.
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									symbols := make([]string, 0, len(sym))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for s := range sym {
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										symbols = append(symbols, s)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sort.Strings(symbols)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									const headerSize = 4
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-20 20:10:37 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putBE32int(len(symbols))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.symbols = make(map[string]uint32, len(symbols))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									for index, s := range symbols {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-18 14:46:22 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										w.symbols[s] = uint32(index)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarintStr(s)
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 05:12:16 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:23:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE32int(w.buf2.len())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putHash(w.crc32)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 23:21:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err := w.write(w.buf1.get(), w.buf2.get())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return errors.Wrap(err, "write symbols")
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 05:27:43 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) WriteLabelIndex(names []string, values []string) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if len(values)%len(names) != 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Errorf("invalid value list length %d for %d names", len(values), len(names))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.ensureStage(idxStageLabelIndex); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Wrap(err, "ensure stage")
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-19 21:01:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									valt, err := NewStringTuples(values, len(names))
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-12 18:38:43 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:40:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-12 18:38:43 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sort.Sort(valt)
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:40:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Align beginning to 4 bytes for more efficient index list scans.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.addPadding(4); err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 05:12:16 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.labelIndexes = append(w.labelIndexes, hashEntry{
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										keys:   names,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										offset: w.pos,
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 05:12:16 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:01:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putBE32int(len(names))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putBE32int(valt.Len())
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 04:40:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 12:37:57 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									// here we have an index for the symbol file if v2, otherwise it's an offset
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, v := range valt.s {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										index, ok := w.symbols[v]
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !ok {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("symbol entry for %q does not exist", v)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 11:19:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										w.buf2.putBE32(index)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:01:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE32int(w.buf2.len())
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:01:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putHash(w.crc32)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err = w.write(w.buf1.get(), w.buf2.get())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return errors.Wrap(err, "write label index")
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// writeOffsetTable writes a sequence of readable hash entries.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) writeOffsetTable(entries []hashEntry) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putBE32int(len(entries))
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, e := range entries {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarint(len(e.keys))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for _, k := range e.keys {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											w.buf2.putUvarintStr(k)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putUvarint64(e.offset)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE32int(w.buf2.len())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putHash(w.crc32)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return w.write(w.buf1.get(), w.buf2.get())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const indexTOCLen = 6*8 + 4
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) writeTOC() error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE64(w.toc.symbols)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE64(w.toc.series)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE64(w.toc.labelIndices)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE64(w.toc.labelIndicesTable)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE64(w.toc.postings)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE64(w.toc.postingsTable)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putHash(w.crc32)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return w.write(w.buf1.get())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) WritePostings(name, value string, it Postings) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 14:33:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.ensureStage(idxStagePostings); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errors.Wrap(err, "ensure stage")
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-02 14:58:54 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Align beginning to 4 bytes for more efficient postings list scans.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.addPadding(4); err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:28:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.postings = append(w.postings, hashEntry{
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										keys:   []string{name, value},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										offset: w.pos,
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-20 20:10:37 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Order of the references in the postings list does not imply order
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// of the series references within the persisted block they are mapped to.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// We have to sort the new references again.
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									refs := w.uint32s[:0]
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-20 20:10:37 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for it.Next() {
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										offset, ok := w.seriesOffsets[it.At()]
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-02 17:34:55 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if !ok {
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("%p series for reference %d not found", w, it.At())
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-02 17:34:55 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-04 22:08:38 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if offset > (1<<32)-1 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("series offset %d exceeds 4 bytes", offset)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										refs = append(refs, uint32(offset))
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-20 20:10:37 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := it.Err(); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sort.Sort(uint32slice(refs))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putBE32int(len(refs))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-20 20:10:37 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, r := range refs {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										w.buf2.putBE32(r)
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-07 02:41:24 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.uint32s = refs
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 16:44:00 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.reset()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf1.putBE32int(w.buf2.len())
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									w.buf2.putHash(w.crc32)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									err := w.write(w.buf1.get(), w.buf2.get())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return errors.Wrap(err, "write postings")
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-03 06:35:02 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type uint32slice []uint32
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s uint32slice) Len() int           { return len(s) }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s uint32slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (s uint32slice) Less(i, j int) bool { return s[i] < s[j] }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 05:12:16 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type hashEntry struct {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									keys   []string
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									offset uint64
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 05:12:16 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (w *Writer) Close() error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.ensureStage(idxStageDone); err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-10 01:34:29 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-25 22:45:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := w.fbuf.Flush(); err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-25 14:24:20 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := fileutil.Fsync(w.f); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return w.f.Close()
							 | 
						
					
						
							
								
									
										
										
										
											2016-12-10 03:45:46 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// StringTuples provides access to a sorted list of string tuples.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type StringTuples interface {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Total number of tuples in the list.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Len() int
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// At returns the tuple at position i.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									At(i int) ([]string, error)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type Reader struct {
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// The underlying byte slice holding the encoded series data.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b   ByteSlice
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									toc indexTOC
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Close that releases the underlying resources of the byte slice.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									c io.Closer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Cached hashmaps of section offsets.
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									labels   map[string]uint64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									postings map[labels.Label]uint64
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Cache of read symbols. Strings that are returned when reading from the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// block are always backed by true strings held in here rather than
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// strings that are backed by byte slices from the mmap'd index file. This
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// prevents memory faults when applications work with read symbols after
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// the block has been unmapped.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									symbols map[uint32]string
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-28 00:29:59 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									dec *Decoder
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-28 00:29:59 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									crc32 hash.Hash32
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									version int
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								var (
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-26 06:12:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									errInvalidSize     = fmt.Errorf("invalid size")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									errInvalidFlag     = fmt.Errorf("invalid flag")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									errInvalidChecksum = fmt.Errorf("invalid checksum")
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// ByteSlice abstracts a byte slice.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type ByteSlice interface {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Len() int
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Range(start, end int) []byte
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type realByteSlice []byte
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (b realByteSlice) Len() int {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return len(b)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (b realByteSlice) Range(start, end int) []byte {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return b[start:end]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (b realByteSlice) Sub(start, end int) ByteSlice {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return b[start:end]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-12 18:40:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// NewReader returns a new IndexReader on the given byte slice. It automatically
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// handles different format versions.
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func NewReader(b ByteSlice) (*Reader, error) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return newReader(b, nil)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-09 01:33:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// NewFileReader returns a new index reader against the given index file.
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func NewFileReader(path string) (*Reader, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									f, err := fileutil.OpenMmapFile(path)
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return newReader(realByteSlice(f.Bytes()), f)
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func newReader(b ByteSlice, c io.Closer) (*Reader, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r := &Reader{
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										b:        b,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										c:        c,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										symbols:  map[uint32]string{},
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										labels:   map[string]uint64{},
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										postings: map[labels.Label]uint64{},
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										crc32:    newCRC32(),
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-13 03:06:20 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									// Verify header.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if b.Len() < 5 {
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(errInvalidSize, "index header")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if m := binary.BigEndian.Uint32(r.b.Range(0, 4)); m != MagicIndex {
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Errorf("invalid magic number %x", m)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									r.version = int(r.b.Range(4, 5)[0])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.version != 1 && r.version != 2 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Errorf("unknown index file version %d", r.version)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := r.readTOC(); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "read TOC")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err := r.readSymbols(int(r.toc.symbols)); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "read symbols")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var err error
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									err = r.readOffsetTable(r.toc.labelIndicesTable, func(key []string, off uint64) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if len(key) != 1 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("unexpected key length %d", len(key))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										r.labels[key[0]] = off
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									})
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "read label index table")
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									err = r.readOffsetTable(r.toc.postingsTable, func(key []string, off uint64) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if len(key) != 2 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Errorf("unexpected key length %d", len(key))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										r.postings[labels.Label{Name: key[0], Value: key[1]}] = off
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "read postings table")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									r.dec = &Decoder{symbols: r.symbols}
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return r, nil
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-22 04:06:19 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Version returns the file format version of the underlying index.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) Version() int {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return r.version
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Range marks a byte range.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type Range struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									Start, End int64
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// PostingsRanges returns a new map of byte range in the underlying index file
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// for all postings lists.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) PostingsRanges() (map[labels.Label]Range, error) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									m := map[labels.Label]Range{}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for l, start := range r.postings {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										d := r.decbufAt(int(start))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return nil, d.err()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										m[l] = Range{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											Start: int64(start) + 4,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											End:   int64(start) + 4 + int64(d.len()),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return m, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) readTOC() error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.b.Len() < indexTOCLen {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return errInvalidSize
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b := r.b.Range(r.b.Len()-indexTOCLen, r.b.Len())
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									expCRC := binary.BigEndian.Uint32(b[len(b)-4:])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := decbuf{b: b[:len(b)-4]}
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if d.crc32() != expCRC {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 01:22:50 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return errors.Wrap(errInvalidChecksum, "read TOC")
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-26 06:12:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r.toc.symbols = d.be64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r.toc.series = d.be64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r.toc.labelIndices = d.be64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r.toc.labelIndicesTable = d.be64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r.toc.postings = d.be64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									r.toc.postingsTable = d.be64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return d.err()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// decbufAt returns a new decoding buffer. It expects the first 4 bytes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// after offset to hold the big endian encoded content length, followed by the contents and the expected
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// checksum.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) decbufAt(off int) decbuf {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.b.Len() < off+4 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errInvalidSize}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b := r.b.Range(off, off+4)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									l := int(binary.BigEndian.Uint32(b))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.b.Len() < off+4+l+4 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errInvalidSize}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Load bytes holding the contents plus a CRC32 checksum.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b = r.b.Range(off+4, off+4+l+4)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dec := decbuf{b: b[:len(b)-4]}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if exp := binary.BigEndian.Uint32(b[len(b)-4:]); dec.crc32() != exp {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errInvalidChecksum}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return dec
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 21:23:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// decbufUvarintAt returns a new decoding buffer. It expects the first bytes
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// after offset to hold the uvarint-encoded buffers length, followed by the contents and the expected
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// checksum.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) decbufUvarintAt(off int) decbuf {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// We never have to access this method at the far end of the byte slice. Thus just checking
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// against the MaxVarintLen32 is sufficient.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.b.Len() < off+binary.MaxVarintLen32 {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errInvalidSize}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b := r.b.Range(off, off+binary.MaxVarintLen32)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									l, n := binary.Uvarint(b)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if n > binary.MaxVarintLen32 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errors.New("invalid uvarint")}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.b.Len() < off+n+int(l)+4 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errInvalidSize}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Load bytes holding the contents plus a CRC32 checksum.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b = r.b.Range(off+n, off+n+int(l)+4)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dec := decbuf{b: b[:len(b)-4]}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if dec.crc32() != binary.BigEndian.Uint32(b[len(b)-4:]) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return decbuf{e: errInvalidChecksum}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return dec
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// readSymbols reads the symbol table fully into memory and allocates proper strings for them.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Strings backed by the mmap'd memory would cause memory faults if applications keep using them
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// after the reader is closed.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) readSymbols(off int) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if off == 0 {
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := r.decbufAt(off)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									var (
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										origLen = d.len()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cnt     = d.be32int()
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										basePos = uint32(off) + 4
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nextPos = basePos + uint32(origLen-d.len())
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 12:37:57 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if r.version == 2 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										nextPos = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for d.err() == nil && d.len() > 0 && cnt > 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										s := d.uvarintStr()
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-22 04:23:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										r.symbols[nextPos] = s
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 12:37:57 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if r.version == 2 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nextPos++
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											nextPos = basePos + uint32(origLen-d.len())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cnt--
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 01:22:50 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return errors.Wrap(d.err(), "read symbols")
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// readOffsetTable reads an offset table at the given position calls f for each
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// found entry.f
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// If f returns an error it stops decoding and returns the received error,
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) readOffsetTable(off uint64, f func([]string, uint64) error) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := r.decbufAt(int(off))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									cnt := d.be32()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for d.err() == nil && d.len() > 0 && cnt > 0 {
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-22 04:23:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										keyCount := d.uvarint()
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										keys := make([]string, 0, keyCount)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for i := 0; i < keyCount; i++ {
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											keys = append(keys, d.uvarintStr())
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-02 15:46:23 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										o := d.uvarint64()
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err := f(keys, o); err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return err
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										cnt--
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return d.err()
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Close the reader and its underlying resources.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) Close() error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return r.c.Close()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) lookupSymbol(o uint32) (string, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									s, ok := r.symbols[o]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if !ok {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "", errors.Errorf("unknown symbol offset %d", o)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 02:32:34 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return s, nil
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:40:52 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Symbols returns a set of symbols that exist within the index.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) Symbols() (map[string]struct{}, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									res := make(map[string]struct{}, len(r.symbols))
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for _, s := range r.symbols {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										res[s] = struct{}{}
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-02 21:56:57 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return res, nil
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// SymbolTable returns the symbol table that is used to resolve symbol references.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) SymbolTable() map[uint32]string {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return r.symbols
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// LabelValues returns value tuples that exist for the given label name tuples.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) LabelValues(names ...string) (StringTuples, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									const sep = "\xff"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									key := strings.Join(names, sep)
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									off, ok := r.labels[key]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if !ok {
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-20 18:37:06 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// XXX(fabxc): hot fix. Should return a partial data error and handle cases
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										// where the entire block has no data gracefully.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return emptyStringTuples{}, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										//return nil, fmt.Errorf("label index doesn't exist")
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := r.decbufAt(int(off))
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-26 01:01:25 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									nc := d.be32int()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d.be32() // consume unused value entry count.
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(d.err(), "read label value index")
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-27 03:34:31 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									st := &serializedStringTuples{
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-28 20:17:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										l:      nc,
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										b:      d.get(),
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lookup: r.lookupSymbol,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return st, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-20 18:37:06 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type emptyStringTuples struct{}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (emptyStringTuples) At(i int) ([]string, error) { return nil, nil }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (emptyStringTuples) Len() int                   { return 0 }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// LabelIndices returns a for which labels or label tuples value indices exist.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) LabelIndices() ([][]string, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:01:13 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									const sep = "\xff"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									res := [][]string{}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for s := range r.labels {
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-27 00:03:44 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										res = append(res, strings.Split(s, sep))
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return res, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 15:50:42 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Series reads the series with the given ID and writes its labels and chunks into lbls and chks.
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) Series(id uint64, lbls *labels.Labels, chks *[]chunks.Meta) error {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									offset := id
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									// In version 2 series IDs are no longer exact references but series are 16-byte padded
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// and the ID is the multiple of 16 of the actual position.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if r.version == 2 {
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-09 20:11:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										offset = id * 16
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := r.decbufUvarintAt(int(offset))
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return d.err()
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-17 01:22:50 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return errors.Wrap(r.dec.Series(d.get(), lbls, chks), "read series")
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Postings returns a postings list for the given label pair.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) Postings(name, value string) (Postings, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 18:01:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									off, ok := r.postings[labels.Label{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Name:  name,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Value: value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}]
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if !ok {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return EmptyPostings(), nil
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-10 01:27:09 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := r.decbufAt(int(off))
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(d.err(), "get postings entry")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									_, p, err := r.dec.Postings(d.get())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(err, "decode postings")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return p, nil
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// SortedPostings returns the given postings list reordered so that the backing series
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// are sorted.
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (r *Reader) SortedPostings(p Postings) Postings {
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-05 19:31:48 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return p
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type stringTuples struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									l int      // tuple length
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									s []string // flattened tuple entries
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-11-30 22:34:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func NewStringTuples(s []string, l int) (*stringTuples, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-07 19:47:49 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if len(s)%l != 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errors.Wrap(errInvalidSize, "string tuple list")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return &stringTuples{s: s, l: l}, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (t *stringTuples) Len() int                   { return len(t.s) / t.l }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (t *stringTuples) At(i int) ([]string, error) { return t.s[i : i+t.l], nil }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (t *stringTuples) Swap(i, j int) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									c := make([]string, t.l)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									copy(c, t.s[i:i+t.l])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k := 0; k < t.l; k++ {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										t.s[i+k] = t.s[j+k]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										t.s[j+k] = c[k]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (t *stringTuples) Less(i, j int) bool {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k := 0; k < t.l; k++ {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										d := strings.Compare(t.s[i+k], t.s[j+k])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if d < 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return true
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if d > 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return false
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return false
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								type serializedStringTuples struct {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									l      int
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									b      []byte
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									lookup func(uint32) (string, error)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (t *serializedStringTuples) Len() int {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return len(t.b) / (4 * t.l)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								func (t *serializedStringTuples) At(i int) ([]string, error) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if len(t.b) < (i+t.l)*4 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil, errInvalidSize
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									res := make([]string, 0, t.l)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for k := 0; k < t.l; k++ {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										offset := binary.BigEndian.Uint32(t.b[(i+k)*4:])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										s, err := t.lookup(offset)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return nil, errors.Wrap(err, "symbol lookup")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										res = append(res, s)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return res, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-09 01:33:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								// Decoder provides decoding methods for the v1 and v2 index file format.
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								//
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// It currently does not contain decoding methods for all entry types but can be extended
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// by them if there's demand.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								type Decoder struct {
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-09 01:33:35 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									symbols map[uint32]string
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (dec *Decoder) lookupSymbol(o uint32) (string, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									s, ok := dec.symbols[o]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if !ok {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return "", errors.Errorf("unknown symbol offset %d", o)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return s, nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// SetSymbolTable set the symbol table to be used for lookups when decoding series
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// and label indices
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (dec *Decoder) SetSymbolTable(t map[uint32]string) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									dec.symbols = t
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Postings returns a postings list for b and its number of elements.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (dec *Decoder) Postings(b []byte) (int, Postings, error) {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									d := decbuf{b: b}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									n := d.be32int()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									l := d.get()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return n, newBigEndianPostings(l), d.err()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								// Series decodes a series entry from the given byte slice into lset and chks.
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-11 03:19:16 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								func (dec *Decoder) Series(b []byte, lbls *labels.Labels, chks *[]chunks.Meta) error {
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									*lbls = (*lbls)[:0]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									*chks = (*chks)[:0]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									d := decbuf{b: b}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-22 04:23:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									k := d.uvarint()
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for i := 0; i < k; i++ {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lno := uint32(d.uvarint())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lvo := uint32(d.uvarint())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Wrap(d.err(), "read series label offsets")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ln, err := dec.lookupSymbol(lno)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Wrap(err, "lookup label name")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										lv, err := dec.lookupSymbol(lvo)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if err != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Wrap(err, "lookup label value")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										*lbls = append(*lbls, labels.Label{Name: ln, Value: lv})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									// Read the chunks meta data.
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-22 04:23:47 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									k = d.uvarint()
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-01 19:06:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if k == 0 {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									t0 := d.varint64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									maxt := int64(d.uvarint64()) + t0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ref0 := int64(d.uvarint64())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									*chks = append(*chks, chunks.Meta{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										Ref:     uint64(ref0),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										MinTime: t0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										MaxTime: maxt,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									t0 = maxt
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									for i := 1; i < k; i++ {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mint := int64(d.uvarint64()) + t0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										maxt := int64(d.uvarint64()) + mint
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ref0 += d.varint64()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										t0 = maxt
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if d.err() != nil {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return errors.Wrapf(d.err(), "read meta for chunk %d", i)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										*chks = append(*chks, chunks.Meta{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											Ref:     uint64(ref0),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											MinTime: mint,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											MaxTime: maxt,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return d.err()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |