Source code: com/fetish/directory/SearchSet.java
1 package com.fetish.directory;
2
3 import net.jini.core.lookup.ServiceMatches;
4 import net.jini.core.lookup.ServiceID;
5 import java.util.*;
6
7 /**
8 * Set of started searches.
9 * This class is stored in a FADA node to keep track of all searches started
10 * from this node.
11 */
12 public class SearchSet implements java.io.Serializable {
13
14 private static long delayTime = 3600000L; // One hour before deleting
15 /** Counter used to construct the id's of the searches */
16 private long numSearches = 0;
17 private ServiceID sid;
18 private SearchIDFactory sidfactory;
19
20 /** Currently running searches indexed by the SearchID */
21 private Map content;
22 private Thread ager = null;
23 private Object lock = new Object();
24
25 private class Ager implements Runnable {
26 SearchID next = null;
27 boolean newData = true;
28 public void run() {
29 while( true ) {
30 // Acquire lock
31 synchronized( lock ) {
32 // Get next
33 next = null;
34 while( next == null ) {
35 while( content.size() == 0 ) {
36 try {
37 lock.wait(); // Wait until there is something
38 } catch( Exception e ) {
39 }
40 }
41 next = choose();
42 }
43 // Compute sleepTime
44 long sleepTime = ((Search)content.get( next )).getExpiryDate() - System.currentTimeMillis();
45 // Wait amount of time
46 long before = 0;
47 long after = 0;
48 if( sleepTime > 0 ) {
49 before = System.currentTimeMillis();
50 try {
51 lock.wait( sleepTime );
52 } catch( Exception e ) {
53 }
54 after = System.currentTimeMillis();
55 }
56 if( after - before >= sleepTime ) {
57 // Delete entry
58 content.remove( next );
59 }
60 }
61 }
62 }
63 private SearchID choose() {
64 long shortestTime = Long.MAX_VALUE;
65 SearchID chosen = null;
66 if( content.size() == 0 ) {
67 return null;
68 } else {
69 Object[] sids = content.keySet().toArray();
70 for( int i = 0; i < sids.length; i++ ) {
71 SearchID actualSid = ( SearchID )sids[i];
72 long actualExpiryDate =
73 ( ( Search )content.get( actualSid ) ).getExpiryDate();
74 if( shortestTime > actualExpiryDate ) {
75 chosen = actualSid;
76 shortestTime = actualExpiryDate;
77 }
78 }
79 return chosen;
80 }
81 }
82 }
83
84 public SearchSet( ServiceID sid ) {
85 this.sid = sid;
86 this.sidfactory = new SearchIDFactory( sid );
87 this.content = new HashMap();
88 this.ager = new Thread( new Ager() );
89 this.ager.start();
90 }
91
92 public SearchIDInterface newSearch( int maxResponses ) {
93 SearchID newSid = this.sidfactory.getSearchID();
94 Search search = new Search( newSid, maxResponses );
95 synchronized( lock ) {
96 ( ( HashMap )this.content ).put( newSid, search );
97 }
98 return newSid;
99 }
100
101 public void startedSearches( SearchIDInterface sid, int started ) {
102 if( ( ( HashMap )content).containsKey( sid ) ) {
103 Search search = ( Search )content.get( sid );
104 if( search != null ) {
105 search.startedSearches( started );
106 }
107 }
108 }
109
110 /**
111 * Add a result to the search identified by id
112 *
113 * @param id identifier of the search being modified
114 * @param sm service matches to be added to the search
115 *
116 */
117 public void addResult ( SearchIDInterface id, ServiceMatches sm ) {
118
119 if( content.containsKey( id ) ) {
120 Search search = ( Search )content.get( id );
121 search.addResult(sm);
122 }
123 }
124
125 public void addResult( ServiceID sid, SearchIDInterface searchID, ServiceMatches sm ) {
126 if( !content.containsKey( searchID ) ) {
127 } else {
128 Search search = ( Search )content.get( searchID );
129 search.addResult( sid, sm );
130 }
131 }
132
133 public void finishedSearch( SearchIDInterface sid ) {
134 if( content.containsKey( sid ) ) {
135 Search search = ( Search )content.get( sid );
136 search.finishedSearch();
137 }
138 }
139
140 /**
141 * Wait for the search process specified to be finished and the return the
142 * results. The search will not exceed the time specified by
143 * Search.MAX_WAIT_TIME
144 *
145 * @param id search
146 * @return service matches for the search specified
147 */
148 public ServiceMatches getResults ( SearchIDInterface id ) {
149
150 Search search = (Search) content.get(id);
151 if( search == null ) {
152 return null;
153 }
154 search.setExpiryDate( System.currentTimeMillis() + delayTime );
155 synchronized( lock ) {
156 lock.notify();
157 }
158
159 // This call will pause the thread waiting for results
160 ServiceMatches result = search.getResults();
161 if( result != null )
162 if( result.items != null )
163
164 // free the reference to the search to allow it be garbage collected
165 content.remove(id);
166
167 return result;
168 }
169
170 }