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:
Bjoern Rabenstein 2014-09-09 14:36:26 +02:00
parent af77d5ef0b
commit 89f10e8eb2
9 changed files with 198 additions and 123 deletions

View file

@ -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() {

View file

@ -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 }

View file

@ -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)
} }
} }
} }

View file

@ -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
}

View file

@ -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),

View file

@ -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()
} }

View file

@ -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 {

View file

@ -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()
}

View file

@ -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
} }