001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.hbtop;
019
020import edu.umd.cs.findbugs.annotations.NonNull;
021import java.util.AbstractMap;
022import java.util.Collection;
023import java.util.Map;
024import java.util.Set;
025import java.util.stream.Stream;
026import org.apache.hadoop.hbase.hbtop.field.Field;
027import org.apache.hadoop.hbase.hbtop.field.FieldValue;
028import org.apache.hadoop.hbase.hbtop.field.FieldValueType;
029import org.apache.yetus.audience.InterfaceAudience;
030
031import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableMap;
032
033/**
034 * Represents a record of the metrics in the top screen.
035 */
036@InterfaceAudience.Private
037public final class Record implements Map<Field, FieldValue> {
038
039  private final ImmutableMap<Field, FieldValue> values;
040
041  public final static class Entry extends AbstractMap.SimpleImmutableEntry<Field, FieldValue> {
042    private Entry(Field key, FieldValue value) {
043      super(key, value);
044    }
045  }
046
047  public final static class Builder {
048
049    private final ImmutableMap.Builder<Field, FieldValue> builder;
050
051    private Builder() {
052      builder = ImmutableMap.builder();
053    }
054
055    public Builder put(Field key, Object value) {
056      builder.put(key, key.newValue(value));
057      return this;
058    }
059
060    public Builder put(Field key, FieldValue value) {
061      builder.put(key, value);
062      return this;
063    }
064
065    public Builder put(Entry entry) {
066      builder.put(entry);
067      return this;
068    }
069
070    public Builder putAll(Map<Field, FieldValue> map) {
071      builder.putAll(map);
072      return this;
073    }
074
075    public Record build() {
076      return new Record(builder.build());
077    }
078  }
079
080  public static Builder builder() {
081    return new Builder();
082  }
083
084  public static Entry entry(Field field, Object value) {
085    return new Entry(field, field.newValue(value));
086  }
087
088  public static Entry entry(Field field, FieldValue value) {
089    return new Entry(field, value);
090  }
091
092  public static Record ofEntries(Entry... entries) {
093    return ofEntries(Stream.of(entries));
094  }
095
096  public static Record ofEntries(Stream<Entry> entries) {
097    return entries.collect(Record::builder, Builder::put, (r1, r2) -> {}).build();
098  }
099
100  private Record(ImmutableMap<Field, FieldValue> values) {
101    this.values = values;
102  }
103
104  @Override
105  public int size() {
106    return values.size();
107  }
108
109  @Override
110  public boolean isEmpty() {
111    return values.isEmpty();
112  }
113
114  @Override
115  public boolean containsKey(Object key) {
116    return values.containsKey(key);
117  }
118
119  @Override
120  public boolean containsValue(Object value) {
121    return values.containsValue(value);
122  }
123
124  @Override
125  public FieldValue get(Object key) {
126    return values.get(key);
127  }
128
129  @Override
130  public FieldValue put(Field key, FieldValue value) {
131    throw new UnsupportedOperationException();
132  }
133
134  @Override
135  public FieldValue remove(Object key) {
136    throw new UnsupportedOperationException();
137  }
138
139  @Override
140  public void putAll(@NonNull Map<? extends Field, ? extends FieldValue> m) {
141    throw new UnsupportedOperationException();
142  }
143
144  @Override
145  public void clear() {
146    throw new UnsupportedOperationException();
147  }
148
149  @Override
150  @NonNull
151  public Set<Field> keySet() {
152    return values.keySet();
153  }
154
155  @Override
156  @NonNull
157  public Collection<FieldValue> values() {
158    return values.values();
159  }
160
161  @Override
162  @NonNull
163  public Set<Map.Entry<Field, FieldValue>> entrySet() {
164    return values.entrySet();
165  }
166
167  public Record combine(Record o) {
168    return ofEntries(values.keySet().stream()
169      .map(k -> {
170        if (k.getFieldValueType() == FieldValueType.STRING) {
171          return entry(k, values.get(k));
172        }
173        return entry(k, values.get(k).plus(o.values.get(k)));
174      }));
175  }
176}