Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: Freenet/node/StandardMessageHandler.java


1   package Freenet.node;
2   import Freenet.*;
3   import java.util.*;
4   import Freenet.support.*;
5   /*
6     This code is part of the Java Adaptive Network Client by Ian Clarke. 
7     It is distributed under the GNU Public Licence (GPL) version 2.  See
8     http://www.gnu.org/ for further details of the GPL.
9   
10    Explanation of Code Versions: 
11      0.0.0      = Initial Description
12      0.0.1      = API Specified
13      0.x (x>0)  = Partial Implementation
14      x.0 (x>0)  = Operational
15      
16   */
17  
18  /**
19   * This class handles incoming messages.
20   *
21   * @version $Revision: 1.3 $
22   * @author <A HREF="mailto:I.Clarke@strs.co.uk">Ian Clarke</A>
23   **/
24  
25  public class StandardMessageHandler implements MessageHandler
26  {
27    // Public Fields
28    // Protected/Private Fields
29  
30    public Node node;
31    private LimitedHashtable messageMemories;
32    private LimitedHashtable tickets;
33    
34    public static void main(String[] args)
35      {
36        System.out.println("Testing limitedHashtable");
37        Hashtable t = new LimitedHashtable(3);
38        t.put(new Integer(1), new String("one"));
39        System.out.println(t.toString());
40        t.put(new Integer(2), new String("two"));
41        System.out.println(t.toString());
42        t.put(new Integer(3), new String("three"));
43        System.out.println(t.toString());
44        t.put(new Integer(4), new String("four"));
45        System.out.println(t.toString());
46        t.put(new Integer(5), new String("five"));
47        System.out.println(t.toString());
48        t.put(new Integer(6), new String("six"));
49        System.out.println(t.toString());
50      }
51  
52    // Constructors
53  
54    /**
55     * @param n The node that should be used to send messages
56     *          and for which the datastore should be updated
57     * @param m The number of message objects that will be
58     *          remembered
59     **/
60    public StandardMessageHandler(Node n, int m)
61      {
62        node = n;
63        messageMemories = new LimitedHashtable(m);
64        tickets = new LimitedHashtable(m);
65      }
66  
67    // Public Methods
68  
69    /**
70     * Handle a message
71     * @param message The message to handle
72     **/
73    public void handle(Message message)
74      {
75        try {
76    Long longid = new Long(message.id);
77    Object ticket = getTicket(longid);
78    synchronized(ticket) {
79      MessageMemory mm = (MessageMemory)messageMemories.get(longid);
80      MessageMemory newmm = message.received(node, mm);
81      if (newmm != mm) {
82        messageMemories.remove(longid);
83        if (newmm != null) {
84          Object[] lmm = messageMemories.limput(longid, newmm);
85          if (lmm != null) { // dispose of lost mm
86        ((MessageMemory) lmm[1]).lost((Long) lmm[0]);
87          }
88        }
89      }
90    }
91        } catch(Exception e) {e.printStackTrace();}
92      }
93  
94    // Protected/Private Methods
95  
96    // Return the canonical object corresponding to the messageid
97    // Create one if it does not already exist.  Synchronize to
98    // protect against race conditions.
99    synchronized Object getTicket(Long longid)
100   {
101     Object ticket = tickets.get(longid);
102     if (ticket == null) {
103       ticket = new Object();
104       tickets.put(longid, ticket);
105     }
106     return ticket;
107   }
108 
109 }
110 
111 
112 /**
113  * A variant on a Hashtable which only holds a limited number of
114  * messages.  When more messages than that are put in, old ones are
115  * deleted, oldest first.
116  *
117  * @version Rrevision$
118  * @author <A HREF="mailto:I.Clarke@strs.co.uk">Ian Clarke</A>
119  **/
120 class LimitedHashtable extends Hashtable
121 {
122   Object[] ar;
123   int ptr = 0;
124   public LimitedHashtable(int size)
125     {
126       super();
127       ar = new Object[size];
128     }
129 
130     /**
131      * @return  If an old object was pushed out of Hashtable by this
132      *          insert, it's an array containing it's key (0) and data (1) 
133      *           is returned. Otherwise null. Observe that 
134      *          any object previously under this key will _not_ be
135      *          returned (use normal put for that).
136      **/
137   public synchronized Object[] limput(Object key, Object value)
138     {
139       Object[] old = null;
140       if (ar[ptr] != null)
141   {
142       Object oldkey = ar[ptr];
143       Object oldvalue = remove(ar[ptr]);
144       if (oldvalue != null) {
145     old = new Object[2];
146     old[0] = oldkey;
147     old[1] = oldvalue;
148       }
149   }
150       ar[ptr] = key;
151       ptr++;
152       if (ptr == ar.length)
153   {
154     ptr = 0;
155   }
156       super.put(key,value);
157       return old;
158     }
159 
160   public synchronized Object put(Object key, Object value)
161     {
162       if (ar[ptr] != null)
163   {
164     remove(ar[ptr]);
165   }
166       ar[ptr] = key;
167       ptr++;
168       if (ptr == ar.length)
169   {
170     ptr = 0;
171   }
172       return super.put(key,value);
173     }
174 
175   public String toString()
176     {
177       return super.toString() + ", max: "+ar.length;
178     }
179 }