Skip to content

Commit

Permalink
Universal Image Loader updated - our changes applied too
Browse files Browse the repository at this point in the history
  • Loading branch information
Grzegorz Nittner committed Apr 23, 2013
1 parent 5ded816 commit 5159070
Show file tree
Hide file tree
Showing 73 changed files with 6,667 additions and 1,119 deletions.
@@ -1,27 +1,53 @@
/*******************************************************************************
* Copyright 2011-2013 Sergey Tarasevich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.nostra13.universalimageloader.cache.disc;

import java.io.File;

import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.core.DefaultConfigurationFactory;

/**
* Base disc cache. Implements common functionality for disc cache.
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.0.0
* @see DiscCacheAware
* @see FileNameGenerator
*/
public abstract class BaseDiscCache implements DiscCacheAware {

private File cacheDir;
private static final String ERROR_ARG_NULL = "\"%s\" argument must be not null";

protected File cacheDir;

private FileNameGenerator fileNameGenerator;

public BaseDiscCache(File cacheDir) {
this(cacheDir, FileNameGenerator.createDefault());
this(cacheDir, DefaultConfigurationFactory.createFileNameGenerator());
}

public BaseDiscCache(File cacheDir, FileNameGenerator fileNameGenerator) {
if (cacheDir == null) {
throw new IllegalArgumentException("cacheDir" + ERROR_ARG_NULL);
}
if (fileNameGenerator == null) {
throw new IllegalArgumentException("fileNameGenerator" + ERROR_ARG_NULL);
}

this.cacheDir = cacheDir;
this.fileNameGenerator = fileNameGenerator;
}
Expand All @@ -41,8 +67,4 @@ public void clear() {
}
}
}

protected File getCacheDir() {
return cacheDir;
}
}
@@ -1,3 +1,18 @@
/*******************************************************************************
* Copyright 2011-2013 Sergey Tarasevich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.nostra13.universalimageloader.cache.disc;

import java.io.File;
Expand All @@ -6,9 +21,9 @@
* Interface for disc cache
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.0.0
*/
public interface DiscCacheAware {

/**
* This method must not to save file on file system in fact. It is called after image was cached in cache directory
* and it was decoded to bitmap in memory. Such order is required to prevent possible deletion of file after it was
Expand Down
@@ -1,3 +1,18 @@
/*******************************************************************************
* Copyright 2011-2013 Sergey Tarasevich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.nostra13.universalimageloader.cache.disc;

import java.io.File;
Expand All @@ -6,72 +21,79 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.core.DefaultConfigurationFactory;

/**
* Abstract disc cache limited by some parameter. If cache exceeds specified limit then file with the most oldest last
* usage date will be deleted.
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.0.0
* @see BaseDiscCache
* @see FileNameGenerator
*/
public abstract class LimitedDiscCache extends BaseDiscCache {

private int cacheSize = 0;
private final AtomicInteger cacheSize;

private int sizeLimit;
private final int sizeLimit;

private final Map<File, Long> lastUsageDates = Collections.synchronizedMap(new HashMap<File, Long>());

/**
* @param cacheDir
* Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's needed
* for right cache limit work.
* @param sizeLimit
* Cache limit value. If cache exceeds this limit then file with the most oldest last usage date will be
* deleted.
* @param cacheDir Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's
* needed for right cache limit work.
* @param sizeLimit Cache limit value. If cache exceeds this limit then file with the most oldest last usage date
* will be deleted.
*/
public LimitedDiscCache(File cacheDir, int sizeLimit) {
this(cacheDir, FileNameGenerator.createDefault(), sizeLimit);
this(cacheDir, DefaultConfigurationFactory.createFileNameGenerator(), sizeLimit);
}

/**
* @param cacheDir
* Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's needed
* for right cache limit work.
* @param fileNameGenerator
* Name generator for cached files
* @param sizeLimit
* Cache limit value. If cache exceeds this limit then file with the most oldest last usage date will be
* deleted.
* @param cacheDir Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's
* needed for right cache limit work.
* @param fileNameGenerator Name generator for cached files
* @param sizeLimit Cache limit value. If cache exceeds this limit then file with the most oldest last usage date
* will be deleted.
*/
public LimitedDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, int sizeLimit) {
super(cacheDir, fileNameGenerator);
this.sizeLimit = sizeLimit;
cacheSize = new AtomicInteger();
calculateCacheSizeAndFillUsageMap();
}

private void calculateCacheSizeAndFillUsageMap() {
int size = 0;
File[] cachedFiles = getCacheDir().listFiles();
for (File cachedFile : cachedFiles) {
size += getSize(cachedFile);
lastUsageDates.put(cachedFile, cachedFile.lastModified());
}
cacheSize = size;
new Thread(new Runnable() {
@Override
public void run() {
int size = 0;
File[] cachedFiles = cacheDir.listFiles();
if (cachedFiles != null) { // rarely but it can happen, don't know why
for (File cachedFile : cachedFiles) {
size += getSize(cachedFile);
lastUsageDates.put(cachedFile, cachedFile.lastModified());
}
cacheSize.set(size);
}
}
}).start();
}

@Override
public void put(String key, File file) {
int valueSize = getSize(file);
while (cacheSize + valueSize > sizeLimit) {
int curCacheSize = cacheSize.get();
while (curCacheSize + valueSize > sizeLimit) {
int freedSize = removeNext();
if (freedSize == 0) break; // cache is empty (have nothing to delete)
cacheSize -= freedSize;
curCacheSize = cacheSize.addAndGet(-freedSize);
}
cacheSize += valueSize;
cacheSize.addAndGet(valueSize);

Long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
Expand All @@ -92,7 +114,7 @@ public File get(String key) {
@Override
public void clear() {
lastUsageDates.clear();
cacheSize = 0;
cacheSize.set(0);
super.clear();
}

Expand Down
@@ -1,40 +1,51 @@
/*******************************************************************************
* Copyright 2011-2013 Sergey Tarasevich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.nostra13.universalimageloader.cache.disc.impl;

import java.io.File;

import com.nostra13.universalimageloader.cache.disc.LimitedDiscCache;
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.core.DefaultConfigurationFactory;

/**
* Disc cache limited by file count. If file count in cache directory exceeds specified limit then file with the most
* oldest last usage date will be deleted.
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.0.0
* @see LimitedDiscCache
*/
public class FileCountLimitedDiscCache extends LimitedDiscCache {

/**
* @param cacheDir
* Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's needed
* for right cache limit work.
* @param maxFileCount
* Maximum file count for cache. If file count in cache directory exceeds this limit then file with the
* most oldest last usage date will be deleted.
* @param cacheDir Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's
* needed for right cache limit work.
* @param maxFileCount Maximum file count for cache. If file count in cache directory exceeds this limit then file
* with the most oldest last usage date will be deleted.
*/
public FileCountLimitedDiscCache(File cacheDir, int maxFileCount) {
this(cacheDir, FileNameGenerator.createDefault(), maxFileCount);
this(cacheDir, DefaultConfigurationFactory.createFileNameGenerator(), maxFileCount);
}

/**
* @param cacheDir
* Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's needed
* for right cache limit work.
* @param fileNameGenerator
* Name generator for cached files
* @param maxFileCount
* Maximum file count for cache. If file count in cache directory exceeds this limit then file with the
* most oldest last usage date will be deleted.
* @param cacheDir Directory for file caching. <b>Important:</b> Specify separate folder for cached files. It's
* needed for right cache limit work.
* @param fileNameGenerator Name generator for cached files
* @param maxFileCount Maximum file count for cache. If file count in cache directory exceeds this limit then file
* with the most oldest last usage date will be deleted.
*/
public FileCountLimitedDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, int maxFileCount) {
super(cacheDir, fileNameGenerator, maxFileCount);
Expand Down
@@ -1,3 +1,18 @@
/*******************************************************************************
* Copyright 2011-2013 Sergey Tarasevich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.nostra13.universalimageloader.cache.disc.impl;

import java.io.File;
Expand All @@ -7,11 +22,13 @@

import com.nostra13.universalimageloader.cache.disc.BaseDiscCache;
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.core.DefaultConfigurationFactory;

/**
* Cache which deletes files which were loaded more than defined time. Cache size is unlimited.
*
* @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
* @since 1.3.1
* @see BaseDiscCache
*/
public class LimitedAgeDiscCache extends BaseDiscCache {
Expand All @@ -21,36 +38,23 @@ public class LimitedAgeDiscCache extends BaseDiscCache {
private final Map<File, Long> loadingDates = Collections.synchronizedMap(new HashMap<File, Long>());

/**
* @param cacheDir
* Directory for file caching
* @param maxAge
* Max file age (in seconds). If file age will exceed this value then it'll be removed on next treatment
* (and therefore be reloaded).
* @param cacheDir Directory for file caching
* @param maxAge Max file age (in seconds). If file age will exceed this value then it'll be removed on next
* treatment (and therefore be reloaded).
*/
public LimitedAgeDiscCache(File cacheDir, long maxAge) {
this(cacheDir, FileNameGenerator.createDefault(), maxAge);
this(cacheDir, DefaultConfigurationFactory.createFileNameGenerator(), maxAge);
}

/**
* @param cacheDir
* Directory for file caching
* @param fileNameGenerator
* Name generator for cached files
* @param maxAge
* Max file age (in seconds). If file age will exceed this value then it'll be removed on next treatment
* (and therefore be reloaded).
* @param cacheDir Directory for file caching
* @param fileNameGenerator Name generator for cached files
* @param maxAge Max file age (in seconds). If file age will exceed this value then it'll be removed on next
* treatment (and therefore be reloaded).
*/
public LimitedAgeDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, long maxAge) {
super(cacheDir, fileNameGenerator);
this.maxFileAge = maxAge * 1000; // to milliseconds
readLoadingDates();
}

private void readLoadingDates() {
File[] cachedFiles = getCacheDir().listFiles();
for (File cachedFile : cachedFiles) {
loadingDates.put(cachedFile, cachedFile.lastModified());
}
}

@Override
Expand All @@ -64,13 +68,20 @@ public void put(String key, File file) {
public File get(String key) {
File file = super.get(key);
if (file.exists()) {
boolean cached;
Long loadingDate = loadingDates.get(file);
if (loadingDate == null) {
cached = false;
loadingDate = file.lastModified();
} else {
cached = true;
}

if (System.currentTimeMillis() - loadingDate > maxFileAge) {
file.delete();
loadingDates.remove(file);
} else if (!cached) {
loadingDates.put(file, loadingDate);
}
}
return file;
Expand Down

0 comments on commit 5159070

Please sign in to comment.