001/*
002 * $Id$
003 */
004
005package edu.jas.util;
006
007
008import java.io.Serializable;
009import java.io.IOException;
010import java.rmi.MarshalledObject;
011
012
013/**
014 * Transport container for a distributed version of a HashTable. 
015 * <b>Note:</b> Contains code for timing of marshalled versus plain 
016 * object serialization which can be removed later.
017 * @author Heinz Kredel
018 */
019public abstract class DHTTransport<K, V> implements Serializable {
020
021
022    static long etime  = 0L; // encode marshalled
023    static long dtime  = 0L; // decode marshalled
024    static long ertime = 0L; // encode plain raw
025    static long drtime = 0L; // decode plain raw
026
027
028    public static enum Stor { // storage and transport class
029        marshal, plain
030    };
031
032
033    public static final Stor stor = Stor.marshal; //Stor.plain; 
034
035
036    /**
037     * protected constructor.
038     */
039    protected DHTTransport() {
040    }
041
042
043    /**
044     * Create a new DHTTransport Container.
045     * @param key
046     * @param value
047     */
048    public static <K,V> DHTTransport<K,V> create(K key, V value) throws IOException {
049        switch (stor) {
050        case marshal: return new DHTTransportMarshal<K,V>(key,value);
051        case plain:   return new DHTTransportPlain<K,V>(key,value);
052        default: throw new IllegalArgumentException("this should not happen");
053        }
054    }
055
056
057    /**
058     * Get the key from this DHTTransport Container.
059     */
060    public abstract K key() throws IOException, ClassNotFoundException;
061
062
063    /**
064     * Get the value from this DHTTransport Container.
065     */
066    public abstract V value() throws IOException, ClassNotFoundException;
067
068
069    /**
070     * toString.
071     */
072    @Override
073    public String toString() {
074        return this.getClass().getName();
075
076    }
077
078}
079
080
081/**
082 * Transport container to signal termination for a distributed version
083 * of a HashTable. Contains no objects.
084 */
085class DHTTransportTerminate<K, V> extends DHTTransport<K, V> {
086
087    /**
088     * Get the key from this DHTTransport Container.
089     */
090    public K key() throws IOException, ClassNotFoundException {
091        throw new UnsupportedOperationException("this should not happen");
092    }
093
094
095    /**
096     * Get the value from this DHTTransport Container.
097     */
098    public V value() throws IOException, ClassNotFoundException {
099        throw new UnsupportedOperationException("this should not happen");
100    }
101
102}
103
104
105/**
106 * Transport container to signal clearing contents of the 
107 * other HashTables including the server. Contains no objects.
108 */
109class DHTTransportClear<K, V> extends DHTTransport<K, V> {
110
111    /**
112     * Get the key from this DHTTransport Container.
113     */
114    public K key() throws IOException, ClassNotFoundException {
115        throw new UnsupportedOperationException("this should not happen");
116    }
117
118
119    /**
120     * Get the value from this DHTTransport Container.
121     */
122    public V value() throws IOException, ClassNotFoundException {
123        throw new UnsupportedOperationException("this should not happen");
124    }
125
126}
127
128
129/**
130 * Transport container for a distributed version of a HashTable. Immutable
131 * objects. Uses MarshalledObject to avoid deserialization on server side.
132 */
133class DHTTransportMarshal<K, V> extends DHTTransport<K, V> {
134
135
136    protected final MarshalledObject/*<K>*/ key;
137
138
139    protected final MarshalledObject/*<V>*/ value;
140
141
142    /**
143     * Constructs a new DHTTransport Container.
144     * @param key
145     * @param value
146     */
147    @SuppressWarnings("unchecked")
148    public DHTTransportMarshal(K key, V value) throws IOException {
149        long t = System.currentTimeMillis();
150        this.key = new MarshalledObject/*<K>*/(key);
151        this.value = new MarshalledObject/*<V>*/(value);
152        t = System.currentTimeMillis() - t;
153        synchronized( DHTTransport.class ) {
154            etime += t;
155        }
156        //System.out.println("         marshal time = " + t);
157    }
158
159
160    /**
161     * Get the key from this DHTTransport Container.
162     */
163    @SuppressWarnings("unchecked")
164    public K key() throws IOException, ClassNotFoundException {
165        long t = System.currentTimeMillis();
166        K k = (K) this.key.get();
167        t = System.currentTimeMillis() - t;
168        synchronized( DHTTransport.class ) {
169            dtime += t;
170        }
171        return k;
172    }
173
174
175    /**
176     * Get the value from this DHTTransport Container.
177     */
178    @SuppressWarnings("unchecked")
179    public V value() throws IOException, ClassNotFoundException {
180        long t = System.currentTimeMillis();
181        V v = (V) this.value.get();
182        t = System.currentTimeMillis() - t;
183        synchronized( DHTTransport.class ) {
184            dtime += t;
185        }
186        return v;
187    }
188
189
190    /**
191     * toString.
192     */
193    @Override
194    public String toString() {
195        return super.toString() + "(" + key + "," + value + ")";
196    }
197
198
199    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
200        long t = System.currentTimeMillis();
201        out.defaultWriteObject();
202        t = System.currentTimeMillis() - t;
203        synchronized( DHTTransport.class ) {
204            ertime += t;
205        }
206    }
207
208
209    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
210        long t = System.currentTimeMillis();
211        in.defaultReadObject();
212        t = System.currentTimeMillis() - t; // not meaningful, includes waiting time
213        synchronized( DHTTransport.class ) {
214            drtime += t;
215        }
216    }
217
218}
219
220
221/**
222 * Transport container for a distributed version of a HashTable. Immutable
223 * objects. Uses plain objects.
224 */
225class DHTTransportPlain<K, V> extends DHTTransport<K, V> {
226
227
228    protected final K key;
229
230
231    protected final V value;
232
233
234    /**
235     * Constructs a new DHTTransport Container.
236     * @param key
237     * @param value
238     */
239    public DHTTransportPlain(K key, V value) throws IOException {
240        this.key = key;
241        this.value = value;
242    }
243
244
245    /**
246     * Get the key from this DHTTransport Container.
247     */
248    public K key() throws IOException, ClassNotFoundException {
249        return this.key;
250    }
251
252
253    /**
254     * Get the value from this DHTTransport Container.
255     */
256    public V value() throws IOException, ClassNotFoundException {
257        return this.value;
258    }
259
260
261    /**
262     * toString.
263     */
264    @Override
265    public String toString() {
266        return super.toString() + "(" + key + "," + value + ")";
267    }
268
269
270    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
271        long t = System.currentTimeMillis();
272        out.defaultWriteObject();
273        t = System.currentTimeMillis() - t;
274        synchronized( DHTTransport.class ) {
275            ertime += t;
276        }
277    }
278
279
280    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
281        long t = System.currentTimeMillis();
282        in.defaultReadObject();
283        t = System.currentTimeMillis() - t;
284        synchronized( DHTTransport.class ) {
285            drtime += t;
286        }
287    }
288
289}