/projects/azureus-4.7.0.2/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionManager.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 613 lines · 400 code · 192 blank · 21 comment · 69 complexity · fc7aff37f950a9b532f5511935940952 MD5 · raw file

  1. /*
  2. * Created on 24-Apr-2006
  3. * Created by Paul Gardner
  4. * Copyright (C) 2006 Aelitis, All Rights Reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. *
  18. * AELITIS, SAS au capital de 46,603.30 euros
  19. * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
  20. *
  21. */
  22. package com.aelitis.azureus.core.dht.netcoords;
  23. import java.io.ByteArrayInputStream;
  24. import java.io.ByteArrayOutputStream;
  25. import java.io.DataInputStream;
  26. import java.io.DataOutputStream;
  27. import java.io.IOException;
  28. import java.net.InetAddress;
  29. import java.util.ArrayList;
  30. import java.util.Iterator;
  31. import java.util.List;
  32. import org.gudy.azureus2.core3.util.Debug;
  33. import com.aelitis.azureus.core.dht.DHTStorageAdapter;
  34. import com.aelitis.azureus.core.dht.impl.DHTLog;
  35. import com.aelitis.azureus.core.util.CopyOnWriteList;
  36. public class
  37. DHTNetworkPositionManager
  38. {
  39. private static DHTNetworkPositionProvider[] providers = new DHTNetworkPositionProvider[0];
  40. private static DHTStorageAdapter storage_adapter = null;
  41. private static CopyOnWriteList<DHTNetworkPositionProviderListener> provider_listeners = new CopyOnWriteList<DHTNetworkPositionProviderListener>();
  42. private static CopyOnWriteList<DHTNetworkPositionListener> position_listeners;
  43. public static void
  44. initialise(
  45. DHTStorageAdapter adapter )
  46. {
  47. synchronized( providers ){
  48. if ( storage_adapter == null ){
  49. storage_adapter = adapter;
  50. for (int i=0;i<providers.length;i++){
  51. DHTNetworkPositionProvider provider = providers[i];
  52. try{
  53. startUp( provider );
  54. }catch( Throwable e ){
  55. Debug.printStackTrace(e);
  56. }
  57. }
  58. }
  59. }
  60. }
  61. private static void
  62. startUp(
  63. DHTNetworkPositionProvider provider )
  64. {
  65. byte[] data = null;
  66. if ( storage_adapter != null ){
  67. data = storage_adapter.getStorageForKey( "NPP:" + provider.getPositionType());
  68. }
  69. if ( data == null ){
  70. data = new byte[0];
  71. }
  72. try{
  73. provider.startUp( new DataInputStream( new ByteArrayInputStream( data )));
  74. }catch( Throwable e ){
  75. Debug.printStackTrace( e );
  76. }
  77. }
  78. private static void
  79. shutDown(
  80. DHTNetworkPositionProvider provider )
  81. {
  82. try{
  83. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  84. DataOutputStream dos = new DataOutputStream( baos );
  85. provider.shutDown( dos );
  86. dos.flush();
  87. byte[] data = baos.toByteArray();
  88. storage_adapter.setStorageForKey( "NPP:" + provider.getPositionType(), data );
  89. }catch( Throwable e ){
  90. Debug.printStackTrace( e );
  91. }
  92. }
  93. public static void
  94. destroy(
  95. DHTStorageAdapter adapter )
  96. {
  97. synchronized( providers ){
  98. if ( storage_adapter == adapter ){
  99. for (int i=0;i<providers.length;i++){
  100. shutDown( providers[i] );
  101. }
  102. storage_adapter = null;
  103. }
  104. }
  105. }
  106. public static DHTNetworkPositionProviderInstance
  107. registerProvider(
  108. final DHTNetworkPositionProvider provider )
  109. {
  110. boolean fire_added = false;
  111. synchronized( providers ){
  112. boolean found = false;
  113. DHTNetworkPositionProvider type_found = null;
  114. for ( DHTNetworkPositionProvider p: providers ){
  115. if ( p == provider ){
  116. found = true;
  117. break;
  118. }else if ( p.getPositionType() == provider.getPositionType()){
  119. type_found = p;
  120. }
  121. }
  122. if ( !found ){
  123. if ( type_found != null ){
  124. Debug.out( "Registration of " + provider + " found previous provider for same position type, removing it" );
  125. unregisterProviderSupport( type_found );
  126. }
  127. DHTNetworkPositionProvider[] new_providers = new DHTNetworkPositionProvider[providers.length + 1 ];
  128. System.arraycopy( providers, 0, new_providers, 0, providers.length );
  129. new_providers[providers.length] = provider;
  130. providers = new_providers;
  131. if ( storage_adapter != null ){
  132. startUp( provider );
  133. }
  134. fire_added = true;
  135. }
  136. }
  137. if ( fire_added ){
  138. for ( DHTNetworkPositionProviderListener l: provider_listeners ){
  139. try{
  140. l.providerAdded( provider );
  141. }catch( Throwable e ){
  142. Debug.out( e );
  143. }
  144. }
  145. }
  146. return( new DHTNetworkPositionProviderInstance()
  147. {
  148. public void
  149. log(
  150. String log )
  151. {
  152. DHTLog.log("NetPos " + provider.getPositionType() + ": " + log );
  153. }
  154. });
  155. }
  156. public static void
  157. unregisterProvider(
  158. DHTNetworkPositionProvider provider )
  159. {
  160. if ( unregisterProviderSupport( provider )){
  161. for ( DHTNetworkPositionProviderListener l: provider_listeners ){
  162. try{
  163. l.providerRemoved( provider );
  164. }catch( Throwable e ){
  165. Debug.out( e );
  166. }
  167. }
  168. }
  169. }
  170. private static boolean
  171. unregisterProviderSupport(
  172. DHTNetworkPositionProvider provider )
  173. {
  174. boolean removed = false;
  175. synchronized( providers ){
  176. if ( providers.length == 0 ){
  177. return( false );
  178. }
  179. DHTNetworkPositionProvider[] new_providers = new DHTNetworkPositionProvider[providers.length - 1 ];
  180. int pos = 0;
  181. for ( int i=0;i<providers.length;i++){
  182. if ( providers[i] == provider ){
  183. if ( storage_adapter != null ){
  184. shutDown( provider );
  185. }
  186. }else{
  187. new_providers[pos++] = providers[i];
  188. }
  189. }
  190. if ( pos == new_providers.length ){
  191. providers = new_providers;
  192. removed = true;
  193. }
  194. }
  195. return( removed );
  196. }
  197. public static DHTNetworkPositionProvider
  198. getProvider(
  199. byte type )
  200. {
  201. synchronized( providers ){
  202. for (int i=0;i<providers.length;i++){
  203. if ( providers[i].getPositionType() == type ){
  204. return( providers[i] );
  205. }
  206. }
  207. }
  208. return( null );
  209. }
  210. public static DHTNetworkPosition[]
  211. getLocalPositions()
  212. {
  213. DHTNetworkPositionProvider[] prov = providers;
  214. List<DHTNetworkPosition> res = new ArrayList<DHTNetworkPosition>();
  215. for (int i=0;i<prov.length;i++){
  216. try{
  217. DHTNetworkPosition pos = prov[i].getLocalPosition();
  218. if ( pos != null ){
  219. res.add( pos );
  220. }
  221. }catch( Throwable e ){
  222. Debug.printStackTrace(e);
  223. }
  224. }
  225. return( res.toArray(new DHTNetworkPosition[res.size()]));
  226. }
  227. public static DHTNetworkPosition
  228. getBestLocalPosition()
  229. {
  230. DHTNetworkPosition best_position = null;
  231. DHTNetworkPosition[] positions = getLocalPositions();
  232. byte best_provider = DHTNetworkPosition.POSITION_TYPE_NONE;
  233. for (int i=0;i<positions.length;i++){
  234. DHTNetworkPosition position = positions[i];
  235. int type = position.getPositionType();
  236. if ( type > best_provider ){
  237. best_position = position;
  238. }
  239. }
  240. return( best_position );
  241. }
  242. public static DHTNetworkPosition[]
  243. createPositions(
  244. byte[] ID,
  245. boolean is_local )
  246. {
  247. DHTNetworkPositionProvider[] prov = providers;
  248. DHTNetworkPosition[] res = new DHTNetworkPosition[prov.length];
  249. int skipped = 0;
  250. for (int i=0;i<res.length;i++){
  251. try{
  252. res[i] = prov[i].create( ID, is_local );
  253. }catch( Throwable e ){
  254. Debug.printStackTrace(e);
  255. skipped++;
  256. }
  257. }
  258. if ( skipped > 0 ){
  259. DHTNetworkPosition[] x = new DHTNetworkPosition[ res.length - skipped ];
  260. int pos = 0;
  261. for (int i=0;i<res.length;i++){
  262. if ( res[i] != null ){
  263. x[pos++] = res[i];
  264. }
  265. }
  266. res = x;
  267. if ( res.length == 0 ){
  268. Debug.out( "hmm" );
  269. }
  270. }
  271. return( res );
  272. }
  273. public static float
  274. estimateRTT(
  275. DHTNetworkPosition[] p1s,
  276. DHTNetworkPosition[] p2s )
  277. {
  278. byte best_provider = DHTNetworkPosition.POSITION_TYPE_NONE;
  279. float best_result = Float.NaN;
  280. for (int i=0;i<p1s.length;i++){
  281. DHTNetworkPosition p1 = p1s[i];
  282. byte p1_type = p1.getPositionType();
  283. for (int j=0;j<p2s.length;j++){
  284. DHTNetworkPosition p2 = p2s[j];
  285. if ( p1_type == p2.getPositionType()){
  286. try{
  287. float f = p1.estimateRTT( p2 );
  288. if ( !Float.isNaN( f )){
  289. if ( p1_type > best_provider ){
  290. best_result = f;
  291. best_provider = p1_type;
  292. }
  293. }
  294. }catch( Throwable e ){
  295. Debug.printStackTrace(e);
  296. }
  297. break;
  298. }
  299. }
  300. }
  301. return( best_result );
  302. }
  303. public static void
  304. update(
  305. DHTNetworkPosition[] local_positions,
  306. byte[] remote_id,
  307. DHTNetworkPosition[] remote_positions,
  308. float rtt )
  309. {
  310. for (int i=0;i<local_positions.length;i++){
  311. DHTNetworkPosition p1 = local_positions[i];
  312. for (int j=0;j<remote_positions.length;j++){
  313. DHTNetworkPosition p2 = remote_positions[j];
  314. if ( p1.getPositionType() == p2.getPositionType()){
  315. try{
  316. p1.update( remote_id, p2, rtt );
  317. }catch( Throwable e ){
  318. Debug.printStackTrace(e);
  319. }
  320. break;
  321. }
  322. }
  323. }
  324. }
  325. public static byte[]
  326. serialisePosition(
  327. DHTNetworkPosition pos )
  328. throws IOException
  329. {
  330. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  331. DataOutputStream dos = new DataOutputStream( baos );
  332. dos.writeByte( 1 ); // version
  333. dos.writeByte( pos.getPositionType());
  334. pos.serialise( dos );
  335. dos.close();
  336. return( baos.toByteArray());
  337. }
  338. public static DHTNetworkPosition
  339. deserialisePosition(
  340. InetAddress originator,
  341. byte[] bytes )
  342. throws IOException
  343. {
  344. ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
  345. DataInputStream dis = new DataInputStream( bais );
  346. dis.readByte(); // version
  347. byte position_type = dis.readByte();
  348. return( deserialise( originator, position_type, dis ));
  349. }
  350. public static DHTNetworkPosition
  351. deserialise(
  352. InetAddress originator,
  353. byte position_type,
  354. DataInputStream is )
  355. throws IOException
  356. {
  357. DHTNetworkPositionProvider[] prov = providers;
  358. is.mark( 512 );
  359. for (int i=0;i<prov.length;i++){
  360. if ( prov[i].getPositionType() == position_type ){
  361. DHTNetworkPositionProvider provider = prov[i];
  362. try{
  363. DHTNetworkPosition np = provider.deserialisePosition( is );
  364. CopyOnWriteList<DHTNetworkPositionListener> listeners = position_listeners;
  365. if ( listeners != null ){
  366. Iterator<DHTNetworkPositionListener> it = listeners.iterator();
  367. while( it.hasNext()){
  368. try{
  369. it.next().positionFound( provider, originator, np );
  370. }catch( Throwable e ){
  371. Debug.printStackTrace(e);
  372. }
  373. }
  374. }
  375. return( np );
  376. }catch( Throwable e ){
  377. Debug.printStackTrace(e);
  378. is.reset();
  379. }
  380. break;
  381. }
  382. }
  383. return( null );
  384. }
  385. public static void
  386. addPositionListener(
  387. DHTNetworkPositionListener listener )
  388. {
  389. synchronized( DHTNetworkPositionManager.class ){
  390. if ( position_listeners == null ){
  391. position_listeners = new CopyOnWriteList<DHTNetworkPositionListener>();
  392. }
  393. position_listeners.add( listener );
  394. }
  395. }
  396. public static void
  397. removePositionListener(
  398. DHTNetworkPositionListener listener )
  399. {
  400. synchronized( DHTNetworkPositionManager.class ){
  401. if ( position_listeners != null ){
  402. position_listeners.remove( listener );
  403. if ( position_listeners.size() == 0 ){
  404. position_listeners = null;
  405. }
  406. }
  407. }
  408. }
  409. public static void
  410. addProviderListener(
  411. DHTNetworkPositionProviderListener listener )
  412. {
  413. provider_listeners.add( listener );
  414. }
  415. public static void
  416. removeProviderListener(
  417. DHTNetworkPositionProviderListener listener )
  418. {
  419. provider_listeners.remove( listener );
  420. }
  421. }