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