mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-10 07:34:04 -08:00
Move to using the standard library interfaces for encoding/decoding.
BinaryMarshaler instead of encodable. BinaryUnmarshaler instead of decodable. Left 'codable' in place for lack of a better word. Change-Id: I8a104be7d6db916e8dbc47ff95e6ff73b845ac22
This commit is contained in:
parent
af77d5ef0b
commit
89f10e8eb2
|
@ -1,6 +1,8 @@
|
||||||
package index
|
package index
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,12 +10,26 @@ type batch struct {
|
||||||
batch *leveldb.Batch
|
batch *leveldb.Batch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *batch) Put(key, value encodable) {
|
func (b *batch) Put(key, value encoding.BinaryMarshaler) error {
|
||||||
b.batch.Put(key.encode(), value.encode())
|
k, err := key.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v, err := value.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.batch.Put(k, v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *batch) Delete(k encodable) {
|
func (b *batch) Delete(key encoding.BinaryMarshaler) error {
|
||||||
b.batch.Delete(k.encode())
|
k, err := key.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.batch.Delete(k)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *batch) Reset() {
|
func (b *batch) Reset() {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package index
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -12,16 +13,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type codable interface {
|
type codable interface {
|
||||||
encodable
|
encoding.BinaryMarshaler
|
||||||
decodable
|
encoding.BinaryUnmarshaler
|
||||||
}
|
|
||||||
|
|
||||||
type encodable interface {
|
|
||||||
encode() []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type decodable interface {
|
|
||||||
decode([]byte)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: yeah, this ain't ideal. A lot of locking and possibly even contention.
|
// TODO: yeah, this ain't ideal. A lot of locking and possibly even contention.
|
||||||
|
@ -36,27 +29,29 @@ func setTmpBufLen(l int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeVarint(b *bytes.Buffer, i int) {
|
func encodeVarint(b *bytes.Buffer, i int) error {
|
||||||
tmpBufMtx.Lock()
|
tmpBufMtx.Lock()
|
||||||
defer tmpBufMtx.Unlock()
|
defer tmpBufMtx.Unlock()
|
||||||
|
|
||||||
bytesWritten := binary.PutVarint(tmpBuf, int64(i))
|
bytesWritten := binary.PutVarint(tmpBuf, int64(i))
|
||||||
if _, err := b.Write(tmpBuf[:bytesWritten]); err != nil {
|
if _, err := b.Write(tmpBuf[:bytesWritten]); err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeString(b *bytes.Buffer, s string) {
|
func encodeString(b *bytes.Buffer, s string) error {
|
||||||
encodeVarint(b, len(s))
|
encodeVarint(b, len(s))
|
||||||
if _, err := b.WriteString(s); err != nil {
|
if _, err := b.WriteString(s); err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeString(b *bytes.Reader) string {
|
func decodeString(b *bytes.Reader) (string, error) {
|
||||||
length, err := binary.ReadVarint(b)
|
length, err := binary.ReadVarint(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpBufMtx.Lock()
|
tmpBufMtx.Lock()
|
||||||
|
@ -64,51 +59,59 @@ func decodeString(b *bytes.Reader) string {
|
||||||
|
|
||||||
setTmpBufLen(int(length))
|
setTmpBufLen(int(length))
|
||||||
if _, err := io.ReadFull(b, tmpBuf); err != nil {
|
if _, err := io.ReadFull(b, tmpBuf); err != nil {
|
||||||
panic(err)
|
return "", err
|
||||||
}
|
}
|
||||||
return string(tmpBuf)
|
return string(tmpBuf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableMetric clientmodel.Metric
|
type codableMetric clientmodel.Metric
|
||||||
|
|
||||||
func (m codableMetric) encode() []byte {
|
func (m codableMetric) MarshalBinary() ([]byte, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
encodeVarint(buf, len(m))
|
encodeVarint(buf, len(m))
|
||||||
for l, v := range m {
|
for l, v := range m {
|
||||||
encodeString(buf, string(l))
|
encodeString(buf, string(l))
|
||||||
encodeString(buf, string(v))
|
encodeString(buf, string(v))
|
||||||
}
|
}
|
||||||
return buf.Bytes()
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m codableMetric) decode(buf []byte) {
|
func (m codableMetric) UnmarshalBinary(buf []byte) error {
|
||||||
r := bytes.NewReader(buf)
|
r := bytes.NewReader(buf)
|
||||||
numLabelPairs, err := binary.ReadVarint(r)
|
numLabelPairs, err := binary.ReadVarint(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
for ; numLabelPairs > 0; numLabelPairs-- {
|
for ; numLabelPairs > 0; numLabelPairs-- {
|
||||||
ln := decodeString(r)
|
ln, err := decodeString(r)
|
||||||
lv := decodeString(r)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lv, err := decodeString(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
m[clientmodel.LabelName(ln)] = clientmodel.LabelValue(lv)
|
m[clientmodel.LabelName(ln)] = clientmodel.LabelValue(lv)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableFingerprint clientmodel.Fingerprint
|
type codableFingerprint clientmodel.Fingerprint
|
||||||
|
|
||||||
func (fp codableFingerprint) encode() []byte {
|
func (fp codableFingerprint) MarshalBinary() ([]byte, error) {
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
binary.BigEndian.PutUint64(b, uint64(fp))
|
binary.BigEndian.PutUint64(b, uint64(fp))
|
||||||
return b
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fp *codableFingerprint) decode(buf []byte) {
|
func (fp *codableFingerprint) UnmarshalBinary(buf []byte) error {
|
||||||
*fp = codableFingerprint(binary.BigEndian.Uint64(buf))
|
*fp = codableFingerprint(binary.BigEndian.Uint64(buf))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableFingerprints clientmodel.Fingerprints
|
type codableFingerprints clientmodel.Fingerprints
|
||||||
|
|
||||||
func (fps codableFingerprints) encode() []byte {
|
func (fps codableFingerprints) MarshalBinary() ([]byte, error) {
|
||||||
buf := bytes.NewBuffer(make([]byte, 0, binary.MaxVarintLen64+len(fps)*8))
|
buf := bytes.NewBuffer(make([]byte, 0, binary.MaxVarintLen64+len(fps)*8))
|
||||||
encodeVarint(buf, len(fps))
|
encodeVarint(buf, len(fps))
|
||||||
|
|
||||||
|
@ -119,17 +122,17 @@ func (fps codableFingerprints) encode() []byte {
|
||||||
for _, fp := range fps {
|
for _, fp := range fps {
|
||||||
binary.BigEndian.PutUint64(tmpBuf, uint64(fp))
|
binary.BigEndian.PutUint64(tmpBuf, uint64(fp))
|
||||||
if _, err := buf.Write(tmpBuf[:8]); err != nil {
|
if _, err := buf.Write(tmpBuf[:8]); err != nil {
|
||||||
panic(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.Bytes()
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *codableFingerprints) decode(buf []byte) {
|
func (fps *codableFingerprints) UnmarshalBinary(buf []byte) error {
|
||||||
r := bytes.NewReader(buf)
|
r := bytes.NewReader(buf)
|
||||||
numFPs, err := binary.ReadVarint(r)
|
numFPs, err := binary.ReadVarint(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
*fps = make(codableFingerprints, numFPs)
|
*fps = make(codableFingerprints, numFPs)
|
||||||
|
|
||||||
|
@ -137,64 +140,84 @@ func (fps *codableFingerprints) decode(buf []byte) {
|
||||||
for i, _ := range *fps {
|
for i, _ := range *fps {
|
||||||
(*fps)[i] = clientmodel.Fingerprint(binary.BigEndian.Uint64(buf[offset+i*8:]))
|
(*fps)[i] = clientmodel.Fingerprint(binary.BigEndian.Uint64(buf[offset+i*8:]))
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableLabelPair metric.LabelPair
|
type codableLabelPair metric.LabelPair
|
||||||
|
|
||||||
func (lp codableLabelPair) encode() []byte {
|
func (lp codableLabelPair) MarshalBinary() ([]byte, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
encodeString(buf, string(lp.Name))
|
encodeString(buf, string(lp.Name))
|
||||||
encodeString(buf, string(lp.Value))
|
encodeString(buf, string(lp.Value))
|
||||||
return buf.Bytes()
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lp *codableLabelPair) decode(buf []byte) {
|
func (lp *codableLabelPair) UnmarshalBinary(buf []byte) error {
|
||||||
r := bytes.NewReader(buf)
|
r := bytes.NewReader(buf)
|
||||||
lp.Name = clientmodel.LabelName(decodeString(r))
|
n, err := decodeString(r)
|
||||||
lp.Value = clientmodel.LabelValue(decodeString(r))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v, err := decodeString(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lp.Name = clientmodel.LabelName(n)
|
||||||
|
lp.Value = clientmodel.LabelValue(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableLabelName clientmodel.LabelName
|
type codableLabelName clientmodel.LabelName
|
||||||
|
|
||||||
func (l codableLabelName) encode() []byte {
|
func (l codableLabelName) MarshalBinary() ([]byte, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
encodeString(buf, string(l))
|
encodeString(buf, string(l))
|
||||||
return buf.Bytes()
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *codableLabelName) decode(buf []byte) {
|
func (l *codableLabelName) UnmarshalBinary(buf []byte) error {
|
||||||
r := bytes.NewReader(buf)
|
r := bytes.NewReader(buf)
|
||||||
*l = codableLabelName(decodeString(r))
|
n, err := decodeString(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*l = codableLabelName(n)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableLabelValues clientmodel.LabelValues
|
type codableLabelValues clientmodel.LabelValues
|
||||||
|
|
||||||
func (vs codableLabelValues) encode() []byte {
|
func (vs codableLabelValues) MarshalBinary() ([]byte, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
encodeVarint(buf, len(vs))
|
encodeVarint(buf, len(vs))
|
||||||
for _, v := range vs {
|
for _, v := range vs {
|
||||||
encodeString(buf, string(v))
|
encodeString(buf, string(v))
|
||||||
}
|
}
|
||||||
return buf.Bytes()
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vs *codableLabelValues) decode(buf []byte) {
|
func (vs *codableLabelValues) UnmarshalBinary(buf []byte) error {
|
||||||
r := bytes.NewReader(buf)
|
r := bytes.NewReader(buf)
|
||||||
numValues, err := binary.ReadVarint(r)
|
numValues, err := binary.ReadVarint(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
*vs = make(codableLabelValues, numValues)
|
*vs = make(codableLabelValues, numValues)
|
||||||
|
|
||||||
for i, _ := range *vs {
|
for i, _ := range *vs {
|
||||||
(*vs)[i] = clientmodel.LabelValue(decodeString(r))
|
v, err := decodeString(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
(*vs)[i] = clientmodel.LabelValue(v)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type codableMembership struct{}
|
type codableMembership struct{}
|
||||||
|
|
||||||
func (m codableMembership) encode() []byte {
|
func (m codableMembership) MarshalBinary() ([]byte, error) {
|
||||||
return []byte{}
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m codableMembership) decode(buf []byte) {}
|
func (m codableMembership) UnmarshalBinary(buf []byte) error { return nil }
|
||||||
|
|
|
@ -103,10 +103,15 @@ func TestCodec(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range scenarios {
|
for i, s := range scenarios {
|
||||||
encoded := s.in.encode()
|
encoded, err := s.in.MarshalBinary()
|
||||||
s.out.decode(encoded)
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := s.out.UnmarshalBinary(encoded); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
if !s.equal(s.in, s.out) {
|
if !s.equal(s.in, s.out) {
|
||||||
t.Fatalf("%d. Got: %v; want %v; encoded bytes are: %v", i, s.out, s.in, encoded)
|
t.Errorf("%d. Got: %v; want %v; encoded bytes are: %v", i, s.out, s.in, encoded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ func (i *SynchronizedIndexer) IndexMetrics(b FingerprintMetricMapping) error {
|
||||||
return i.i.IndexMetrics(b)
|
return i.i.IndexMetrics(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalIndexer is a MetricIndexer that indexes all standard facets of a metric
|
// DiskIndexer is a MetricIndexer that indexes all standard facets of a metric
|
||||||
// that a user or the Prometheus subsystem would want to query against:
|
// that a user or the Prometheus subsystem would want to query against:
|
||||||
//
|
//
|
||||||
// <Fingerprint> -> <existence marker>
|
// <Fingerprint> -> <existence marker>
|
||||||
|
@ -218,7 +218,7 @@ func (i *SynchronizedIndexer) IndexMetrics(b FingerprintMetricMapping) error {
|
||||||
//
|
//
|
||||||
// This type supports concurrent queries, but only single writes, and it has no
|
// This type supports concurrent queries, but only single writes, and it has no
|
||||||
// locking semantics to enforce this.
|
// locking semantics to enforce this.
|
||||||
type TotalIndexer struct {
|
type DiskIndexer struct {
|
||||||
FingerprintToMetric *FingerprintMetricIndex
|
FingerprintToMetric *FingerprintMetricIndex
|
||||||
LabelNameToLabelValues *LabelNameLabelValuesIndex
|
LabelNameToLabelValues *LabelNameLabelValuesIndex
|
||||||
LabelPairToFingerprints *LabelPairFingerprintIndex
|
LabelPairToFingerprints *LabelPairFingerprintIndex
|
||||||
|
@ -384,7 +384,7 @@ func extendLabelPairIndex(i *LabelPairFingerprintIndex, b FingerprintMetricMappi
|
||||||
|
|
||||||
// IndexMetrics adds the facets of all unindexed metrics found in the given
|
// IndexMetrics adds the facets of all unindexed metrics found in the given
|
||||||
// FingerprintMetricMapping to the corresponding indices.
|
// FingerprintMetricMapping to the corresponding indices.
|
||||||
func (i *TotalIndexer) IndexMetrics(b FingerprintMetricMapping) error {
|
func (i *DiskIndexer) IndexMetrics(b FingerprintMetricMapping) error {
|
||||||
unindexed, err := findUnindexed(i.FingerprintMembership, b)
|
unindexed, err := findUnindexed(i.FingerprintMembership, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -413,9 +413,8 @@ func (i *TotalIndexer) IndexMetrics(b FingerprintMetricMapping) error {
|
||||||
return i.FingerprintMembership.IndexBatch(unindexed)
|
return i.FingerprintMembership.IndexBatch(unindexed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnindexMetrics removes the facets of all indexed metrics found in the given
|
// UnindexMetrics implements MetricIndexer.
|
||||||
// FingerprintMetricMapping to the corresponding indices.
|
func (i *DiskIndexer) UnindexMetrics(b FingerprintMetricMapping) error {
|
||||||
func (i *TotalIndexer) UnindexMetrics(b FingerprintMetricMapping) error {
|
|
||||||
indexed, err := findIndexed(i.FingerprintMembership, b)
|
indexed, err := findIndexed(i.FingerprintMembership, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -441,14 +440,19 @@ func (i *TotalIndexer) UnindexMetrics(b FingerprintMetricMapping) error {
|
||||||
return i.FingerprintMembership.UnindexBatch(indexed)
|
return i.FingerprintMembership.UnindexBatch(indexed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMetricForFingerprint returns the metric associated with the provided fingerprint.
|
func (i *DiskIndexer) ArchiveMetrics(fp clientmodel.Fingerprint, first, last clientmodel.Timestamp) error {
|
||||||
func (i *TotalIndexer) GetMetricForFingerprint(fp clientmodel.Fingerprint) (clientmodel.Metric, error) {
|
// TODO: implement.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMetricForFingerprint implements MetricIndexer.
|
||||||
|
func (i *DiskIndexer) GetMetricForFingerprint(fp clientmodel.Fingerprint) (clientmodel.Metric, error) {
|
||||||
m, _, err := i.FingerprintToMetric.Lookup(fp)
|
m, _, err := i.FingerprintToMetric.Lookup(fp)
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFingerprintsForLabelPair returns all fingerprints for the provided label pair.
|
// GetFingerprintsForLabelPair implements MetricIndexer.
|
||||||
func (i *TotalIndexer) GetFingerprintsForLabelPair(ln clientmodel.LabelName, lv clientmodel.LabelValue) (clientmodel.Fingerprints, error) {
|
func (i *DiskIndexer) GetFingerprintsForLabelPair(ln clientmodel.LabelName, lv clientmodel.LabelValue) (clientmodel.Fingerprints, error) {
|
||||||
fps, _, err := i.LabelPairToFingerprints.Lookup(&metric.LabelPair{
|
fps, _, err := i.LabelPairToFingerprints.Lookup(&metric.LabelPair{
|
||||||
Name: ln,
|
Name: ln,
|
||||||
Value: lv,
|
Value: lv,
|
||||||
|
@ -456,13 +460,24 @@ func (i *TotalIndexer) GetFingerprintsForLabelPair(ln clientmodel.LabelName, lv
|
||||||
return fps, err
|
return fps, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLabelValuesForLabelName returns all label values associated with a given label name.
|
// GetLabelValuesForLabelName implements MetricIndexer.
|
||||||
func (i *TotalIndexer) GetLabelValuesForLabelName(ln clientmodel.LabelName) (clientmodel.LabelValues, error) {
|
func (i *DiskIndexer) GetLabelValuesForLabelName(ln clientmodel.LabelName) (clientmodel.LabelValues, error) {
|
||||||
lvs, _, err := i.LabelNameToLabelValues.Lookup(ln)
|
lvs, _, err := i.LabelNameToLabelValues.Lookup(ln)
|
||||||
return lvs, err
|
return lvs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasFingerprint returns true if a metric with the given fingerprint has been indexed.
|
// HasFingerprint implements MetricIndexer.
|
||||||
func (i *TotalIndexer) HasFingerprint(fp clientmodel.Fingerprint) (bool, error) {
|
func (i *DiskIndexer) HasFingerprint(fp clientmodel.Fingerprint) (bool, error) {
|
||||||
|
// TODO: modify.
|
||||||
return i.FingerprintMembership.Has(fp)
|
return i.FingerprintMembership.Has(fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *DiskIndexer) HasArchivedFingerprint(clientmodel.Fingerprint) (present bool, first, last clientmodel.Timestamp, err error) {
|
||||||
|
// TODO: implement.
|
||||||
|
return false, 0, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *DiskIndexer) Close() error {
|
||||||
|
// TODO: implement
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ func newTestDB(t *testing.T) (KeyValueStore, test.Closer) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyIndexedState(i int, t *testing.T, b incrementalBatch, indexedFpsToMetrics FingerprintMetricMapping, indexer *TotalIndexer) {
|
func verifyIndexedState(i int, t *testing.T, b incrementalBatch, indexedFpsToMetrics FingerprintMetricMapping, indexer *DiskIndexer) {
|
||||||
for fp, m := range indexedFpsToMetrics {
|
for fp, m := range indexedFpsToMetrics {
|
||||||
// Compare indexed metrics with input metrics.
|
// Compare indexed metrics with input metrics.
|
||||||
mOut, ok, err := indexer.FingerprintToMetric.Lookup(fp)
|
mOut, ok, err := indexer.FingerprintToMetric.Lookup(fp)
|
||||||
|
@ -224,7 +224,7 @@ func TestIndexing(t *testing.T) {
|
||||||
fpMsDB, fpMsCloser := newTestDB(t)
|
fpMsDB, fpMsCloser := newTestDB(t)
|
||||||
defer fpMsCloser.Close()
|
defer fpMsCloser.Close()
|
||||||
|
|
||||||
indexer := TotalIndexer{
|
indexer := DiskIndexer{
|
||||||
FingerprintToMetric: NewFingerprintMetricIndex(fpToMetricDB),
|
FingerprintToMetric: NewFingerprintMetricIndex(fpToMetricDB),
|
||||||
LabelNameToLabelValues: NewLabelNameLabelValuesIndex(lnToLvsDB),
|
LabelNameToLabelValues: NewLabelNameLabelValuesIndex(lnToLvsDB),
|
||||||
LabelPairToFingerprints: NewLabelPairFingerprintIndex(lpToFpDB),
|
LabelPairToFingerprints: NewLabelPairFingerprintIndex(lpToFpDB),
|
||||||
|
|
|
@ -1,16 +1,28 @@
|
||||||
package index
|
package index
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
|
|
||||||
clientmodel "github.com/prometheus/client_golang/model"
|
clientmodel "github.com/prometheus/client_golang/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricIndexer indexes facets of a clientmodel.Metric. The interface makes no
|
// MetricIndexer indexes facets of a clientmodel.Metric. Implementers may or may
|
||||||
// assumptions about the concurrency safety of the underlying implementer.
|
// not be concurrency-safe.
|
||||||
type MetricIndexer interface {
|
type MetricIndexer interface {
|
||||||
// IndexMetrics adds metrics to the index.
|
// IndexMetrics adds metrics to the index. If the metrics was added
|
||||||
|
// before and has been archived in the meantime, it is now un-archived.
|
||||||
IndexMetrics(FingerprintMetricMapping) error
|
IndexMetrics(FingerprintMetricMapping) error
|
||||||
// UnindexMetrics removes metrics from the index.
|
// UnindexMetrics removes metrics from the index.
|
||||||
UnindexMetrics(FingerprintMetricMapping) error
|
UnindexMetrics(FingerprintMetricMapping) error
|
||||||
|
// ArchiveMetrics marks the metric with the given fingerprint as
|
||||||
|
// 'archived', which has to be called if upon eviction of the
|
||||||
|
// corresponding time series from memory. By calling this method, the
|
||||||
|
// MetricIndexer learns about the time range of the evicted time series,
|
||||||
|
// which is used later for the decision if an evicted time series has to
|
||||||
|
// be moved back into memory. The implementer of MetricIndexer can make
|
||||||
|
// use of the archived state, e.g. by saving archived metrics in an
|
||||||
|
// on-disk index and non-archived metrics in an in-memory index.
|
||||||
|
ArchiveMetrics(fp clientmodel.Fingerprint, first, last clientmodel.Timestamp) error
|
||||||
|
|
||||||
// GetMetricForFingerprint returns the metric associated with the provided fingerprint.
|
// GetMetricForFingerprint returns the metric associated with the provided fingerprint.
|
||||||
GetMetricForFingerprint(clientmodel.Fingerprint) (clientmodel.Metric, error)
|
GetMetricForFingerprint(clientmodel.Fingerprint) (clientmodel.Metric, error)
|
||||||
|
@ -18,16 +30,24 @@ type MetricIndexer interface {
|
||||||
GetFingerprintsForLabelPair(l clientmodel.LabelName, v clientmodel.LabelValue) (clientmodel.Fingerprints, error)
|
GetFingerprintsForLabelPair(l clientmodel.LabelName, v clientmodel.LabelValue) (clientmodel.Fingerprints, error)
|
||||||
// GetLabelValuesForLabelName returns all label values associated with a given label name.
|
// GetLabelValuesForLabelName returns all label values associated with a given label name.
|
||||||
GetLabelValuesForLabelName(clientmodel.LabelName) (clientmodel.LabelValues, error)
|
GetLabelValuesForLabelName(clientmodel.LabelName) (clientmodel.LabelValues, error)
|
||||||
// HasFingerprint returns true if a metric with the given fingerprint has been indexed.
|
// HasFingerprint returns true if a metric with the given fingerprint
|
||||||
|
// has been indexed and has NOT been archived yet.
|
||||||
HasFingerprint(clientmodel.Fingerprint) (bool, error)
|
HasFingerprint(clientmodel.Fingerprint) (bool, error)
|
||||||
|
// HasArchivedFingerprint returns true if a metric with the given
|
||||||
|
// fingerprint was indexed before and has been archived in the
|
||||||
|
// meantime. In that case, the time range of the archived metric is also
|
||||||
|
// returned.
|
||||||
|
HasArchivedFingerprint(clientmodel.Fingerprint) (present bool, first, last clientmodel.Timestamp, err error)
|
||||||
|
|
||||||
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyValueStore persists key/value pairs.
|
// KeyValueStore persists key/value pairs.
|
||||||
type KeyValueStore interface {
|
type KeyValueStore interface {
|
||||||
Put(key, value encodable) error
|
Put(key, value encoding.BinaryMarshaler) error
|
||||||
Get(k encodable, v decodable) (bool, error)
|
Get(k encoding.BinaryMarshaler, v encoding.BinaryUnmarshaler) (bool, error)
|
||||||
Has(k encodable) (has bool, err error)
|
Has(k encoding.BinaryMarshaler) (has bool, err error)
|
||||||
Delete(k encodable) error
|
Delete(k encoding.BinaryMarshaler) error
|
||||||
|
|
||||||
NewBatch() Batch
|
NewBatch() Batch
|
||||||
Commit(b Batch) error
|
Commit(b Batch) error
|
||||||
|
@ -37,7 +57,7 @@ type KeyValueStore interface {
|
||||||
|
|
||||||
// Batch allows KeyValueStore mutations to be pooled and committed together.
|
// Batch allows KeyValueStore mutations to be pooled and committed together.
|
||||||
type Batch interface {
|
type Batch interface {
|
||||||
Put(key, value encodable)
|
Put(key, value encoding.BinaryMarshaler) error
|
||||||
Delete(key encodable)
|
Delete(key encoding.BinaryMarshaler) error
|
||||||
Reset()
|
Reset()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package index
|
package index
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/cache"
|
"github.com/syndtr/goleveldb/leveldb/cache"
|
||||||
"github.com/syndtr/goleveldb/leveldb/filter"
|
"github.com/syndtr/goleveldb/leveldb/filter"
|
||||||
|
@ -48,31 +50,46 @@ func (l *LevelDB) Close() error {
|
||||||
return l.storage.Close()
|
return l.storage.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LevelDB) Get(k encodable, v decodable) (bool, error) {
|
func (l *LevelDB) Get(key encoding.BinaryMarshaler, value encoding.BinaryUnmarshaler) (bool, error) {
|
||||||
raw, err := l.storage.Get(k.encode(), l.readOpts)
|
k, err := key.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
raw, err := l.storage.Get(k, l.readOpts)
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if v == nil {
|
if value == nil {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
v.decode(raw)
|
return true, value.UnmarshalBinary(raw)
|
||||||
return true, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LevelDB) Has(k encodable) (has bool, err error) {
|
func (l *LevelDB) Has(key encoding.BinaryMarshaler) (has bool, err error) {
|
||||||
return l.Get(k, nil)
|
return l.Get(key, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LevelDB) Delete(k encodable) error {
|
func (l *LevelDB) Delete(key encoding.BinaryMarshaler) error {
|
||||||
return l.storage.Delete(k.encode(), l.writeOpts)
|
k, err := key.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.storage.Delete(k, l.writeOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LevelDB) Put(key, value encodable) error {
|
func (l *LevelDB) Put(key, value encoding.BinaryMarshaler) error {
|
||||||
return l.storage.Put(key.encode(), value.encode(), l.writeOpts)
|
k, err := key.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v, err := value.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.storage.Put(k, v, l.writeOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LevelDB) Commit(b Batch) error {
|
func (l *LevelDB) Commit(b Batch) error {
|
||||||
|
|
|
@ -2,8 +2,6 @@ package storage_ng
|
||||||
|
|
||||||
import (
|
import (
|
||||||
clientmodel "github.com/prometheus/client_golang/model"
|
clientmodel "github.com/prometheus/client_golang/model"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/storage/local/index"
|
|
||||||
"github.com/prometheus/prometheus/storage/metric"
|
"github.com/prometheus/prometheus/storage/metric"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -64,9 +62,7 @@ type Persistence interface {
|
||||||
LoadHeads(map[clientmodel.Fingerprint]*memorySeries) error
|
LoadHeads(map[clientmodel.Fingerprint]*memorySeries) error
|
||||||
|
|
||||||
// Close releases any held resources.
|
// Close releases any held resources.
|
||||||
Close()
|
Close() error
|
||||||
|
|
||||||
index.MetricIndexer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Preloader preloads series data necessary for a query into memory and pins
|
// A Preloader preloads series data necessary for a query into memory and pins
|
||||||
|
@ -86,8 +82,3 @@ type Preloader interface {
|
||||||
// Close unpins any previously requested series data from memory.
|
// Close unpins any previously requested series data from memory.
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Closer interface {
|
|
||||||
// Close cleans up any used resources.
|
|
||||||
Close()
|
|
||||||
}
|
|
||||||
|
|
|
@ -41,9 +41,9 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fingerprintToMetricCacheSize = flag.Int("storage.fingerprintToMetricCacheSizeBytes", 25*1024*1024, "The size in bytes for the fingerprint to metric index cache.")
|
fingerprintToMetricCacheSize = flag.Int("storage.fingerprintToMetricCacheSizeBytes", 25*1024*1024, "The size in bytes for the fingerprint to metric index cache.")
|
||||||
labelNameToLabelValuesCacheSize = flag.Int("storage.labelNameToLabelValuesCacheSizeBytes", 25*1024*1024, "The size in bytes for the label name to label values index.")
|
labelNameToLabelValuesCacheSize = flag.Int("storage.labelNameToLabelValuesCacheSizeBytes", 25*1024*1024, "The size in bytes for the label name to label values index cache.")
|
||||||
labelPairToFingerprintsCacheSize = flag.Int("storage.labelPairToFingerprintsCacheSizeBytes", 25*1024*1024, "The size in bytes for the label pair to fingerprints index.")
|
labelPairToFingerprintsCacheSize = flag.Int("storage.labelPairToFingerprintsCacheSizeBytes", 25*1024*1024, "The size in bytes for the label pair to fingerprints index cache.")
|
||||||
fingerprintMembershipCacheSize = flag.Int("storage.fingerprintMembershipCacheSizeBytes", 5*1024*1024, "The size in bytes for the metric membership index.")
|
fingerprintMembershipCacheSize = flag.Int("storage.fingerprintMembershipCacheSizeBytes", 5*1024*1024, "The size in bytes for the metric membership index cache.")
|
||||||
)
|
)
|
||||||
|
|
||||||
type diskPersistence struct {
|
type diskPersistence struct {
|
||||||
|
@ -94,7 +94,7 @@ func NewDiskPersistence(basePath string, chunkLen int) (Persistence, error) {
|
||||||
basePath: basePath,
|
basePath: basePath,
|
||||||
chunkLen: chunkLen,
|
chunkLen: chunkLen,
|
||||||
buf: make([]byte, binary.MaxVarintLen64), // Also sufficient for uint64.
|
buf: make([]byte, binary.MaxVarintLen64), // Also sufficient for uint64.
|
||||||
MetricIndexer: &index.TotalIndexer{
|
MetricIndexer: &index.DiskIndexer{
|
||||||
FingerprintToMetric: index.NewFingerprintMetricIndex(fingerprintToMetricDB),
|
FingerprintToMetric: index.NewFingerprintMetricIndex(fingerprintToMetricDB),
|
||||||
LabelNameToLabelValues: index.NewLabelNameLabelValuesIndex(labelNameToLabelValuesDB),
|
LabelNameToLabelValues: index.NewLabelNameLabelValuesIndex(labelNameToLabelValuesDB),
|
||||||
LabelPairToFingerprints: index.NewLabelPairFingerprintIndex(labelPairToFingerprintsDB),
|
LabelPairToFingerprints: index.NewLabelPairFingerprintIndex(labelPairToFingerprintsDB),
|
||||||
|
@ -395,25 +395,13 @@ func (p *diskPersistence) LoadHeads(fpToSeries map[clientmodel.Fingerprint]*memo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *diskPersistence) Close() {
|
func (d *diskPersistence) Close() error {
|
||||||
|
var lastError error
|
||||||
for _, db := range d.indexDBs {
|
for _, db := range d.indexDBs {
|
||||||
if err := db.Close(); err != nil {
|
if err := db.Close(); err != nil {
|
||||||
glog.Error("Error closing index DB: ", err)
|
glog.Error("Error closing index DB: ", err)
|
||||||
|
lastError = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return lastError
|
||||||
|
|
||||||
// Get all of the label values that are associated with a given label name.
|
|
||||||
func (d *diskPersistence) GetFingerprintsForLabelPair(l clientmodel.LabelName, v clientmodel.LabelValue) (clientmodel.Fingerprints, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all label values that are associated with a given label name.
|
|
||||||
func (d *diskPersistence) GetLabelValuesForLabelName(clientmodel.LabelName) (clientmodel.LabelValues, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the metric associated with the provided fingerprint.
|
|
||||||
func (d *diskPersistence) GetMetricForFingerprint(clientmodel.Fingerprint) (clientmodel.Metric, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue