2121package org .biojava .nbio .structure .ecod ;
2222
2323import java .io .IOException ;
24+ import java .lang .ref .SoftReference ;
2425import java .util .Collections ;
2526import java .util .HashMap ;
27+ import java .util .Iterator ;
2628import java .util .Map ;
29+ import java .util .Map .Entry ;
2730
2831import org .biojava .nbio .structure .align .util .UserConfiguration ;
2932import org .biojava .nbio .structure .cath .CathDatabase ;
@@ -46,8 +49,8 @@ public class EcodFactory {
4649
4750 public static String DEFAULT_VERSION = EcodInstallation .DEFAULT_VERSION ;
4851
49- private static Map <String , EcodDatabase > versionedEcodDBs =
50- Collections .synchronizedMap (new HashMap <String , EcodDatabase >());
52+ private static Map <String , SoftReference < EcodDatabase > > versionedEcodDBs =
53+ Collections .synchronizedMap (new HashMap <String , SoftReference < EcodDatabase > >());
5154 private static String defaultVersion = DEFAULT_VERSION ;
5255
5356 /**
@@ -61,27 +64,51 @@ public static EcodDatabase getEcodDatabase(String version) {
6164 if ( version == null )
6265 version = defaultVersion ;
6366
67+ logger .trace ("Waiting for EcodFactory lock to get version " +version );
6468 synchronized (versionedEcodDBs ) {
65- EcodDatabase ecod = versionedEcodDBs .get (version .toLowerCase ());
69+ logger .trace ("Got EcodFactory lock to get version " +version );
70+
71+ releaseReferences ();
72+
73+ SoftReference <EcodDatabase > ecodRef = versionedEcodDBs .get (version .toLowerCase ());
74+ EcodDatabase ecod = null ;
75+ if (ecodRef != null ) {
76+ ecod = ecodRef .get ();
77+ }
6678 if ( ecod == null ) {
67- logger .info ("Creating new {}, version {}" ,EcodInstallation .class .getSimpleName (),version );
79+ logger .debug ("Creating new {}, version {}" ,EcodInstallation .class .getSimpleName (),version );
6880 String cacheDir = new UserConfiguration ().getCacheFilePath ();
6981 ecod = new EcodInstallation (cacheDir , version );
70- versionedEcodDBs .put (version .toLowerCase (), ecod );
82+ versionedEcodDBs .put (version .toLowerCase (), new SoftReference < EcodDatabase >( ecod ) );
7183
7284 // If the parsed version differed from that requested, add that too
7385 try {
7486 if ( ! versionedEcodDBs .containsKey (ecod .getVersion ().toLowerCase ()) ) {
75- versionedEcodDBs .put (ecod .getVersion ().toLowerCase (),ecod );
87+ versionedEcodDBs .put (ecod .getVersion ().toLowerCase (),new SoftReference < EcodDatabase >( ecod ) );
7688 }
7789 } catch (IOException e ) {
7890 // For parsing errors, just use the requested version
7991 }
8092 }
93+ logger .trace ("Releasing EcodFactory lock after getting version " +version );
8194
8295 return ecod ;
8396 }
8497 }
98+
99+ private static void releaseReferences () {
100+ synchronized (versionedEcodDBs ) {
101+ Iterator <Entry <String , SoftReference <EcodDatabase >>> it = versionedEcodDBs .entrySet ().iterator ();
102+ while (it .hasNext ()) {
103+ Entry <String , SoftReference <EcodDatabase >> entry = it .next ();
104+ SoftReference <EcodDatabase > ref = entry .getValue ();
105+ if (ref .get () == null ) {
106+ logger .debug ("Removed version {} from EcodFactory to save memory." ,entry .getKey ());
107+ it .remove ();
108+ }
109+ }
110+ }
111+ }
85112
86113 /**
87114 * Updates the default version
0 commit comments