Extract Label Pair to Fingerprint indexing.

This commit is contained in:
Matt T. Proud 2013-03-14 17:19:45 -07:00
parent 5959cd9e53
commit 532589f728
2 changed files with 153 additions and 126 deletions

View File

@ -43,6 +43,8 @@ const (
hasIndexMetric = "has_index_metric" hasIndexMetric = "has_index_metric"
hasLabelName = "has_label_name" hasLabelName = "has_label_name"
hasLabelPair = "has_label_pair" hasLabelPair = "has_label_pair"
indexLabelNames = "index_label_names"
indexLabelPairs = "index_label_pairs"
indexMetric = "index_metric" indexMetric = "index_metric"
indexMetrics = "index_metrics" indexMetrics = "index_metrics"
rebuildDiskFrontier = "rebuild_disk_frontier" rebuildDiskFrontier = "rebuild_disk_frontier"

View File

@ -269,38 +269,20 @@ func (l *LevelDBMetricPersistence) findUnindexedMetrics(candidates map[model.Fin
return return
} }
// indexMetrics takes groups of samples, determines which ones contain metrics // indexLabelNames accumulates all label name to fingerprint index entries for
// that are unknown to the storage stack, and then proceeds to update all // the dirty metrics, appends the new dirtied metrics, sorts, and bulk updates
// affected indices. // the index to reflect the new state.
func (l *LevelDBMetricPersistence) indexMetrics(fingerprints map[model.Fingerprint]model.Metric) (err error) { func (l *LevelDBMetricPersistence) indexLabelNames(metrics map[model.Fingerprint]model.Metric) (err error) {
begin := time.Now() begin := time.Now()
defer func() { defer func() {
duration := time.Since(begin) duration := time.Since(begin)
recordOutcome(duration, err, map[string]string{operation: indexMetrics, result: success}, map[string]string{operation: indexMetrics, result: failure}) recordOutcome(duration, err, map[string]string{operation: indexLabelNames, result: success}, map[string]string{operation: indexLabelNames, result: failure})
}() }()
var (
absentMetrics map[model.Fingerprint]model.Metric
)
absentMetrics, err = l.findUnindexedMetrics(fingerprints)
if err != nil {
panic(err)
}
// TODO: For the missing fingerprints, determine what label names and pairs
// are absent and act accordingly and append fingerprints.
var (
doneBuildingLabelNameIndex = make(chan interface{})
doneBuildingLabelPairIndex = make(chan interface{})
)
// Update LabelName -> Fingerprint index.
go func() {
labelNameFingerprints := map[model.LabelName]utility.Set{} labelNameFingerprints := map[model.LabelName]utility.Set{}
for fingerprint, metric := range absentMetrics { for fingerprint, metric := range metrics {
for labelName := range metric { for labelName := range metric {
fingerprintSet, ok := labelNameFingerprints[labelName] fingerprintSet, ok := labelNameFingerprints[labelName]
if !ok { if !ok {
@ -309,8 +291,7 @@ func (l *LevelDBMetricPersistence) indexMetrics(fingerprints map[model.Fingerpri
fingerprints, err := l.GetFingerprintsForLabelName(labelName) fingerprints, err := l.GetFingerprintsForLabelName(labelName)
if err != nil { if err != nil {
panic(err) panic(err)
doneBuildingLabelNameIndex <- err return err
return
} }
for _, fingerprint := range fingerprints { for _, fingerprint := range fingerprints {
@ -345,21 +326,29 @@ func (l *LevelDBMetricPersistence) indexMetrics(fingerprints map[model.Fingerpri
batch.Put(coding.NewProtocolBufferEncoder(key), coding.NewProtocolBufferEncoder(value)) batch.Put(coding.NewProtocolBufferEncoder(key), coding.NewProtocolBufferEncoder(value))
} }
err := l.labelNameToFingerprints.Commit(batch) err = l.labelNameToFingerprints.Commit(batch)
if err != nil { if err != nil {
panic(err) panic(err)
doneBuildingLabelNameIndex <- err
return return
} }
doneBuildingLabelNameIndex <- true return
}
// indexLabelPairs accumulates all label pair to fingerprint index entries for
// the dirty metrics, appends the new dirtied metrics, sorts, and bulk updates
// the index to reflect the new state.
func (l *LevelDBMetricPersistence) indexLabelPairs(metrics map[model.Fingerprint]model.Metric) (err error) {
begin := time.Now()
defer func() {
duration := time.Since(begin)
recordOutcome(duration, err, map[string]string{operation: indexLabelPairs, result: success}, map[string]string{operation: indexLabelPairs, result: failure})
}() }()
// Update LabelPair -> Fingerprint index.
go func() {
labelPairFingerprints := map[model.LabelPair]utility.Set{} labelPairFingerprints := map[model.LabelPair]utility.Set{}
for fingerprint, metric := range absentMetrics { for fingerprint, metric := range metrics {
for labelName, labelValue := range metric { for labelName, labelValue := range metric {
labelPair := model.LabelPair{ labelPair := model.LabelPair{
Name: labelName, Name: labelName,
@ -374,8 +363,7 @@ func (l *LevelDBMetricPersistence) indexMetrics(fingerprints map[model.Fingerpri
}) })
if err != nil { if err != nil {
panic(err) panic(err)
doneBuildingLabelPairIndex <- err return err
return
} }
for _, fingerprint := range fingerprints { for _, fingerprint := range fingerprints {
@ -411,27 +399,64 @@ func (l *LevelDBMetricPersistence) indexMetrics(fingerprints map[model.Fingerpri
batch.Put(coding.NewProtocolBufferEncoder(key), coding.NewProtocolBufferEncoder(value)) batch.Put(coding.NewProtocolBufferEncoder(key), coding.NewProtocolBufferEncoder(value))
} }
err := l.labelSetToFingerprints.Commit(batch) err = l.labelSetToFingerprints.Commit(batch)
if err != nil { if err != nil {
panic(err) panic(err)
doneBuildingLabelPairIndex <- true
return return
} }
doneBuildingLabelPairIndex <- true return
}
// indexMetrics takes groups of samples, determines which ones contain metrics
// that are unknown to the storage stack, and then proceeds to update all
// affected indices.
func (l *LevelDBMetricPersistence) indexMetrics(fingerprints map[model.Fingerprint]model.Metric) (err error) {
begin := time.Now()
defer func() {
duration := time.Since(begin)
recordOutcome(duration, err, map[string]string{operation: indexMetrics, result: success}, map[string]string{operation: indexMetrics, result: failure})
}()
var (
absentMetrics map[model.Fingerprint]model.Metric
)
absentMetrics, err = l.findUnindexedMetrics(fingerprints)
if err != nil {
panic(err)
}
if len(absentMetrics) == 0 {
return
}
// TODO: For the missing fingerprints, determine what label names and pairs
// are absent and act accordingly and append fingerprints.
var (
doneBuildingLabelNameIndex = make(chan error)
doneBuildingLabelPairIndex = make(chan error)
)
go func() {
doneBuildingLabelNameIndex <- l.indexLabelNames(absentMetrics)
}()
// Update LabelPair -> Fingerprint index.
go func() {
doneBuildingLabelPairIndex <- l.indexLabelPairs(absentMetrics)
}() }()
makeTopLevelIndex := true makeTopLevelIndex := true
v := <-doneBuildingLabelNameIndex err = <-doneBuildingLabelNameIndex
_, ok := v.(error) if err != nil {
if ok {
panic(err) panic(err)
makeTopLevelIndex = false makeTopLevelIndex = false
} }
v = <-doneBuildingLabelPairIndex err = <-doneBuildingLabelPairIndex
_, ok = v.(error) if err != nil {
if ok {
panic(err) panic(err)
makeTopLevelIndex = false makeTopLevelIndex = false
} }