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 */
018 package org.apache.hadoop.io;
019
020 import java.io.DataInput;
021 import java.io.DataOutput;
022 import java.io.IOException;
023 import java.util.Collection;
024 import java.util.Comparator;
025 import java.util.Map;
026 import java.util.Set;
027 import java.util.SortedMap;
028 import java.util.TreeMap;
029
030 import org.apache.hadoop.classification.InterfaceAudience;
031 import org.apache.hadoop.classification.InterfaceStability;
032 import org.apache.hadoop.util.ReflectionUtils;
033
034 /**
035 * A Writable SortedMap.
036 */
037 @InterfaceAudience.Public
038 @InterfaceStability.Stable
039 public class SortedMapWritable extends AbstractMapWritable
040 implements SortedMap<WritableComparable, Writable> {
041
042 private SortedMap<WritableComparable, Writable> instance;
043
044 /** default constructor. */
045 public SortedMapWritable() {
046 super();
047 this.instance = new TreeMap<WritableComparable, Writable>();
048 }
049
050 /**
051 * Copy constructor.
052 *
053 * @param other the map to copy from
054 */
055 public SortedMapWritable(SortedMapWritable other) {
056 this();
057 copy(other);
058 }
059
060 @Override
061 public Comparator<? super WritableComparable> comparator() {
062 // Returning null means we use the natural ordering of the keys
063 return null;
064 }
065
066 @Override
067 public WritableComparable firstKey() {
068 return instance.firstKey();
069 }
070
071 @Override
072 public SortedMap<WritableComparable, Writable>
073 headMap(WritableComparable toKey) {
074
075 return instance.headMap(toKey);
076 }
077
078 @Override
079 public WritableComparable lastKey() {
080 return instance.lastKey();
081 }
082
083 @Override
084 public SortedMap<WritableComparable, Writable>
085 subMap(WritableComparable fromKey, WritableComparable toKey) {
086
087 return instance.subMap(fromKey, toKey);
088 }
089
090 @Override
091 public SortedMap<WritableComparable, Writable>
092 tailMap(WritableComparable fromKey) {
093
094 return instance.tailMap(fromKey);
095 }
096
097 @Override
098 public void clear() {
099 instance.clear();
100 }
101
102 @Override
103 public boolean containsKey(Object key) {
104 return instance.containsKey(key);
105 }
106
107 @Override
108 public boolean containsValue(Object value) {
109 return instance.containsValue(value);
110 }
111
112 @Override
113 public Set<java.util.Map.Entry<WritableComparable, Writable>> entrySet() {
114 return instance.entrySet();
115 }
116
117 @Override
118 public Writable get(Object key) {
119 return instance.get(key);
120 }
121
122 @Override
123 public boolean isEmpty() {
124 return instance.isEmpty();
125 }
126
127 @Override
128 public Set<WritableComparable> keySet() {
129 return instance.keySet();
130 }
131
132 @Override
133 public Writable put(WritableComparable key, Writable value) {
134 addToMap(key.getClass());
135 addToMap(value.getClass());
136 return instance.put(key, value);
137 }
138
139 @Override
140 public void putAll(Map<? extends WritableComparable, ? extends Writable> t) {
141 for (Map.Entry<? extends WritableComparable, ? extends Writable> e:
142 t.entrySet()) {
143
144 put(e.getKey(), e.getValue());
145 }
146 }
147
148 @Override
149 public Writable remove(Object key) {
150 return instance.remove(key);
151 }
152
153 @Override
154 public int size() {
155 return instance.size();
156 }
157
158 @Override
159 public Collection<Writable> values() {
160 return instance.values();
161 }
162
163 @SuppressWarnings("unchecked")
164 @Override
165 public void readFields(DataInput in) throws IOException {
166 super.readFields(in);
167
168 // Read the number of entries in the map
169
170 int entries = in.readInt();
171
172 // Then read each key/value pair
173
174 for (int i = 0; i < entries; i++) {
175 WritableComparable key =
176 (WritableComparable) ReflectionUtils.newInstance(getClass(
177 in.readByte()), getConf());
178
179 key.readFields(in);
180
181 Writable value = (Writable) ReflectionUtils.newInstance(getClass(
182 in.readByte()), getConf());
183
184 value.readFields(in);
185 instance.put(key, value);
186 }
187 }
188
189 @Override
190 public void write(DataOutput out) throws IOException {
191 super.write(out);
192
193 // Write out the number of entries in the map
194
195 out.writeInt(instance.size());
196
197 // Then write out each key/value pair
198
199 for (Map.Entry<WritableComparable, Writable> e: instance.entrySet()) {
200 out.writeByte(getId(e.getKey().getClass()));
201 e.getKey().write(out);
202 out.writeByte(getId(e.getValue().getClass()));
203 e.getValue().write(out);
204 }
205 }
206
207 @Override
208 public boolean equals(Object obj) {
209 if (this == obj) {
210 return true;
211 }
212
213 if (obj instanceof SortedMapWritable) {
214 Map map = (Map) obj;
215 if (size() != map.size()) {
216 return false;
217 }
218
219 return entrySet().equals(map.entrySet());
220 }
221
222 return false;
223 }
224
225 @Override
226 public int hashCode() {
227 return instance.hashCode();
228 }
229 }