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      /** {@inheritDoc} */
061      public Comparator<? super WritableComparable> comparator() {
062        // Returning null means we use the natural ordering of the keys
063        return null;
064      }
065    
066      /** {@inheritDoc} */
067      public WritableComparable firstKey() {
068        return instance.firstKey();
069      }
070    
071      /** {@inheritDoc} */
072      public SortedMap<WritableComparable, Writable>
073      headMap(WritableComparable toKey) {
074        
075        return instance.headMap(toKey);
076      }
077    
078      /** {@inheritDoc} */
079      public WritableComparable lastKey() {
080        return instance.lastKey();
081      }
082    
083      /** {@inheritDoc} */
084      public SortedMap<WritableComparable, Writable>
085      subMap(WritableComparable fromKey, WritableComparable toKey) {
086        
087        return instance.subMap(fromKey, toKey);
088      }
089    
090      /** {@inheritDoc} */
091      public SortedMap<WritableComparable, Writable>
092      tailMap(WritableComparable fromKey) {
093        
094        return instance.tailMap(fromKey);
095      }
096    
097      /** {@inheritDoc} */
098      public void clear() {
099        instance.clear();
100      }
101    
102      /** {@inheritDoc} */
103      public boolean containsKey(Object key) {
104        return instance.containsKey(key);
105      }
106    
107      /** {@inheritDoc} */
108      public boolean containsValue(Object value) {
109        return instance.containsValue(value);
110      }
111    
112      /** {@inheritDoc} */
113      public Set<java.util.Map.Entry<WritableComparable, Writable>> entrySet() {
114        return instance.entrySet();
115      }
116    
117      /** {@inheritDoc} */
118      public Writable get(Object key) {
119        return instance.get(key);
120      }
121    
122      /** {@inheritDoc} */
123      public boolean isEmpty() {
124        return instance.isEmpty();
125      }
126    
127      /** {@inheritDoc} */
128      public Set<WritableComparable> keySet() {
129        return instance.keySet();
130      }
131    
132      /** {@inheritDoc} */
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      /** {@inheritDoc} */
140      public void putAll(Map<? extends WritableComparable, ? extends Writable> t) {
141        for (Map.Entry<? extends WritableComparable, ? extends Writable> e:
142          t.entrySet()) {
143          
144          instance.put(e.getKey(), e.getValue());
145        }
146      }
147    
148      /** {@inheritDoc} */
149      public Writable remove(Object key) {
150        return instance.remove(key);
151      }
152    
153      /** {@inheritDoc} */
154      public int size() {
155        return instance.size();
156      }
157    
158      /** {@inheritDoc} */
159      public Collection<Writable> values() {
160        return instance.values();
161      }
162    
163      /** {@inheritDoc} */
164      @SuppressWarnings("unchecked")
165      @Override
166      public void readFields(DataInput in) throws IOException {
167        super.readFields(in);
168        
169        // Read the number of entries in the map
170        
171        int entries = in.readInt();
172        
173        // Then read each key/value pair
174        
175        for (int i = 0; i < entries; i++) {
176          WritableComparable key =
177            (WritableComparable) ReflectionUtils.newInstance(getClass(
178                in.readByte()), getConf());
179          
180          key.readFields(in);
181          
182          Writable value = (Writable) ReflectionUtils.newInstance(getClass(
183              in.readByte()), getConf());
184          
185          value.readFields(in);
186          instance.put(key, value);
187        }
188      }
189    
190      /** {@inheritDoc} */
191      @Override
192      public void write(DataOutput out) throws IOException {
193        super.write(out);
194        
195        // Write out the number of entries in the map
196        
197        out.writeInt(instance.size());
198        
199        // Then write out each key/value pair
200        
201        for (Map.Entry<WritableComparable, Writable> e: instance.entrySet()) {
202          out.writeByte(getId(e.getKey().getClass()));
203          e.getKey().write(out);
204          out.writeByte(getId(e.getValue().getClass()));
205          e.getValue().write(out);
206        }
207      }
208    }