for (BaseMetricImpl<?> metric : metrics.values()) {
if (!metric.confChanged && !metric.valueChanged) continue;
synchronized (metric) {
if (metric.confChanged) {
anyConfChanges = true;
pendingWrites.add(new KeyValue(confSubspace.pack(tupleFrom(metric.getType(), metric.getName(), address, DEFAULT_ID, ENABLED_OPTION)),
metric.enabled ? ENABLED_TRUE : ENABLED_FALSE));
metric.confChanged = false;
}
if (metric.valueChanged) {
pendingWrites.add(new KeyValue(dataSubspace.pack(tupleFrom(metric.getType(), metric.getName(), address, DEFAULT_ID)),
metric.encodeValue()));
metric.valueChanged = false;
}
for (int level = 0; level < NLEVELS; level++) {
MetricLevel<?> metricLevel = metric.levels.get(level);
while (true) {
MetricLevelValues values = metricLevel.values.pollFirst();
if (values == null) break;
pendingWrites.add(new KeyValue(dataSubspace.pack(tupleFrom(metric.getType(), metric.getName(), address, DEFAULT_ID, level, values.start)),
values.bytes));
// Continue to fill (will overwrite key with longer value).
if (metricLevel.values.isEmpty() && !values.isFull()) {
metricLevel.values.addLast(values);
break;
}
}
}
}
}
if (anyConfChanges) {
// Signal a change in configuration. We will respond to this change,
// too, but that seemd harmless and difficult to avoid in a general
// way.
byte[] bytes = new byte[16];
random.nextBytes(bytes);
if (logger.isDebugEnabled()) {
logger.debug("Writing {}: {}", METRIC_CONF_CHANGES_KEY, ByteArrayUtil.printable(bytes));
}
pendingWrites.add(new KeyValue(confChangesSubspace.getKey(), bytes));
}
if (!pendingWrites.isEmpty()) {
getDatabase()
.run(new Function<Transaction,Void>() {
@Override