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) -> {
098    }).build();
099  }
100
101  private Record(ImmutableMap<Field, FieldValue> values) {
102    this.values = values;
103  }
104
105  @Override
106  public int size() {
107    return values.size();
108  }
109
110  @Override
111  public boolean isEmpty() {
112    return values.isEmpty();
113  }
114
115  @Override
116  public boolean containsKey(Object key) {
117    return values.containsKey(key);
118  }
119
120  @Override
121  public boolean containsValue(Object value) {
122    return values.containsValue(value);
123  }
124
125  @Override
126  public FieldValue get(Object key) {
127    return values.get(key);
128  }
129
130  @Override
131  public FieldValue put(Field key, FieldValue value) {
132    throw new UnsupportedOperationException();
133  }
134
135  @Override
136  public FieldValue remove(Object key) {
137    throw new UnsupportedOperationException();
138  }
139
140  @Override
141  public void putAll(@NonNull Map<? extends Field, ? extends FieldValue> m) {
142    throw new UnsupportedOperationException();
143  }
144
145  @Override
146  public void clear() {
147    throw new UnsupportedOperationException();
148  }
149
150  @Override
151  @NonNull
152  public Set<Field> keySet() {
153    return values.keySet();
154  }
155
156  @Override
157  @NonNull
158  public Collection<FieldValue> values() {
159    return values.values();
160  }
161
162  @Override
163  @NonNull
164  public Set<Map.Entry<Field, FieldValue>> entrySet() {
165    return values.entrySet();
166  }
167
168  public Record combine(Record o) {
169    return ofEntries(values.keySet().stream().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}