6464 }
6565
6666 private static File getKeyValueCacheDir () {
67+ if (directory == null || !directory .exists ()) {
68+ directory .mkdir ();
69+ }
6770 return directory ;
6871 }
6972
7073 /**
7174 * How many files are in the key-value cache.
7275 */
7376 /* package */ static int size () {
74- return getKeyValueCacheDir ().listFiles ().length ;
77+ File [] files = getKeyValueCacheDir ().listFiles ();
78+ if (files == null ) {
79+ return 0 ;
80+ }
81+ return files .length ;
7582 }
7683
7784 private static File getKeyValueCacheFile (String key ) {
@@ -96,7 +103,7 @@ private static long getKeyValueCacheAge(File cacheFile) {
96103 }
97104 }
98105
99- /* package */ private static File createKeyValueCacheFile (String key ) {
106+ private static File createKeyValueCacheFile (String key ) {
100107 String filename = String .valueOf (new Date ().getTime ()) + '.' + key ;
101108 return new File (getKeyValueCacheDir (), filename );
102109 }
@@ -127,9 +134,7 @@ private static long getKeyValueCacheAge(File cacheFile) {
127134 }
128135 File f = createKeyValueCacheFile (key );
129136 try {
130- FileOutputStream out = new FileOutputStream (f );
131- out .write (value .getBytes ("UTF-8" ));
132- out .close ();
137+ ParseFileUtils .writeByteArrayToFile (f , value .getBytes ("UTF-8" ));
133138 } catch (UnsupportedEncodingException e ) {
134139 // do nothing
135140 } catch (IOException e ) {
@@ -138,38 +143,47 @@ private static long getKeyValueCacheAge(File cacheFile) {
138143
139144 // Check if we should kick out old cache entries
140145 File [] files = getKeyValueCacheDir ().listFiles ();
146+ // We still need this check since dir.mkdir() may fail
147+ if (files == null || files .length == 0 ) {
148+ return ;
149+ }
150+
141151 int numFiles = files .length ;
142152 int numBytes = 0 ;
143153 for (File file : files ) {
144154 numBytes += file .length ();
145155 }
146- if (numFiles > maxKeyValueCacheFiles || numBytes > maxKeyValueCacheBytes ) {
147- // We need to kick out some cache entries.
148- // Sort oldest-first. We touch on read so mtime is really LRU.
149- // Sometimes (i.e. tests) the time of lastModified isn't granular enough,
150- // so we resort
151- // to sorting by the file name which is always prepended with time in ms
152- Arrays .sort (files , new Comparator <File >() {
153- @ Override
154- public int compare (File f1 , File f2 ) {
155- int dateCompare = Long .valueOf (f1 .lastModified ()).compareTo (f2 .lastModified ());
156- if (dateCompare != 0 ) {
157- return dateCompare ;
158- } else {
159- return f1 .getName ().compareTo (f2 .getName ());
160- }
161- }
162- });
163156
164- for ( File file : files ) {
165- numFiles --;
166- numBytes -= file . length () ;
167- file . delete ();
157+ // If we do not need to clear the cache, simply return
158+ if ( numFiles <= maxKeyValueCacheFiles && numBytes <= maxKeyValueCacheBytes ) {
159+ return ;
160+ }
168161
169- if (numFiles <= maxKeyValueCacheFiles && numBytes <= maxKeyValueCacheBytes ) {
170- break ;
162+ // We need to kick out some cache entries.
163+ // Sort oldest-first. We touch on read so mtime is really LRU.
164+ // Sometimes (i.e. tests) the time of lastModified isn't granular enough,
165+ // so we resort
166+ // to sorting by the file name which is always prepended with time in ms
167+ Arrays .sort (files , new Comparator <File >() {
168+ @ Override
169+ public int compare (File f1 , File f2 ) {
170+ int dateCompare = Long .valueOf (f1 .lastModified ()).compareTo (f2 .lastModified ());
171+ if (dateCompare != 0 ) {
172+ return dateCompare ;
173+ } else {
174+ return f1 .getName ().compareTo (f2 .getName ());
171175 }
172176 }
177+ });
178+
179+ for (File file : files ) {
180+ numFiles --;
181+ numBytes -= file .length ();
182+ file .delete ();
183+
184+ if (numFiles <= maxKeyValueCacheFiles && numBytes <= maxKeyValueCacheBytes ) {
185+ break ;
186+ }
173187 }
174188 }
175189 }
0 commit comments