LruDiskCache.java
/*
* Decompiled with CFR 0_132.
*
* Could not load the following classes:
* android.text.TextUtils
*/
package org.xutils.cache;
import android.text.TextUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;
import org.xutils.DbManager;
import org.xutils.cache.DiskCacheEntity;
import org.xutils.cache.DiskCacheFile;
import org.xutils.common.task.PriorityExecutor;
import org.xutils.common.util.FileUtil;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.LogUtil;
import org.xutils.common.util.MD5;
import org.xutils.common.util.ProcessLock;
import org.xutils.config.DbConfigs;
import org.xutils.db.Selector;
import org.xutils.db.sqlite.WhereBuilder;
import org.xutils.ex.DbException;
import org.xutils.ex.FileLockedException;
import org.xutils.x;
public final class LruDiskCache {
private static final HashMap<String, LruDiskCache> DISK_CACHE_MAP = new HashMap(5);
private static final int LIMIT_COUNT = 5000;
private static final long LIMIT_SIZE = 104857600L;
private static final int LOCK_WAIT = 3000;
private static final String CACHE_DIR_NAME = "xUtils_cache";
private static final String TEMP_FILE_SUFFIX = ".tmp";
private boolean available = false;
private final DbManager cacheDb = x.getDb(DbConfigs.HTTP.getConfig());
private File cacheDir;
private long diskCacheSize = 104857600L;
private final Executor trimExecutor = new PriorityExecutor(1, true);
private long lastTrimTime = 0L;
private static final long TRIM_TIME_SPAN = 1000L;
public static synchronized LruDiskCache getDiskCache(String dirName) {
LruDiskCache cache;
if (TextUtils.isEmpty((CharSequence)dirName)) {
dirName = CACHE_DIR_NAME;
}
if ((cache = DISK_CACHE_MAP.get(dirName)) == null) {
cache = new LruDiskCache(dirName);
DISK_CACHE_MAP.put(dirName, cache);
}
return cache;
}
private LruDiskCache(String dirName) {
this.cacheDir = FileUtil.getCacheDir(dirName);
if (this.cacheDir != null && (this.cacheDir.exists() || this.cacheDir.mkdirs())) {
this.available = true;
}
this.deleteNoIndexFiles();
}
public LruDiskCache setMaxSize(long maxSize) {
if (maxSize > 0L) {
long diskFreeSize = FileUtil.getDiskAvailableSize();
this.diskCacheSize = diskFreeSize > maxSize ? maxSize : diskFreeSize;
}
return this;
}
public DiskCacheEntity get(String key) {
if (!this.available || TextUtils.isEmpty((CharSequence)key)) {
return null;
}
DiskCacheEntity result = null;
try {
result = this.cacheDb.selector(DiskCacheEntity.class).where("key", "=", key).findFirst();
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
if (result != null) {
if (result.getExpires() < System.currentTimeMillis()) {
return null;
}
final DiskCacheEntity finalResult = result;
this.trimExecutor.execute(new Runnable(){
@Override
public void run() {
finalResult.setHits(finalResult.getHits() + 1L);
finalResult.setLastAccess(System.currentTimeMillis());
try {
LruDiskCache.this.cacheDb.update(finalResult, "hits", "lastAccess");
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
});
}
return result;
}
public void put(DiskCacheEntity entity) {
if (!this.available || entity == null || TextUtils.isEmpty((CharSequence)entity.getTextContent()) || entity.getExpires() < System.currentTimeMillis()) {
return;
}
try {
this.cacheDb.replace(entity);
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
this.trimSize();
}
public DiskCacheFile getDiskCacheFile(String key) throws InterruptedException {
ProcessLock processLock;
if (!this.available || TextUtils.isEmpty((CharSequence)key)) {
return null;
}
DiskCacheFile result = null;
DiskCacheEntity entity = this.get(key);
if (entity != null && new File(entity.getPath()).exists() && (processLock = ProcessLock.tryLock(entity.getPath(), false, 3000L)) != null && processLock.isValid() && !(result = new DiskCacheFile(entity, entity.getPath(), processLock)).exists()) {
try {
this.cacheDb.delete(entity);
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
result = null;
}
return result;
}
public DiskCacheFile createDiskCacheFile(DiskCacheEntity entity) throws IOException {
if (!this.available || entity == null) {
return null;
}
DiskCacheFile result = null;
entity.setPath(new File(this.cacheDir, MD5.md5(entity.getKey())).getAbsolutePath());
String tempFilePath = entity.getPath() + TEMP_FILE_SUFFIX;
ProcessLock processLock = ProcessLock.tryLock(tempFilePath, true);
if (processLock != null && processLock.isValid()) {
result = new DiskCacheFile(entity, tempFilePath, processLock);
if (!result.getParentFile().exists()) {
result.mkdirs();
}
} else {
throw new FileLockedException(entity.getPath());
}
return result;
}
public void clearCacheFiles() {
IOUtil.deleteFileOrDir(this.cacheDir);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled force condition propagation
* Lifted jumps to return sites
*/
DiskCacheFile commitDiskCacheFile(DiskCacheFile cacheFile) throws IOException {
DiskCacheFile result;
block11 : {
if (cacheFile != null && cacheFile.length() < 1L) {
IOUtil.closeQuietly(cacheFile);
return null;
}
if (!this.available) return null;
if (cacheFile == null) {
return null;
}
result = null;
DiskCacheEntity cacheEntity = cacheFile.cacheEntity;
if (!cacheFile.getName().endsWith(TEMP_FILE_SUFFIX)) return cacheFile;
ProcessLock processLock = null;
DiskCacheFile destFile = null;
try {
String destPath = cacheEntity.getPath();
processLock = ProcessLock.tryLock(destPath, true, 3000L);
if (processLock == null) throw new FileLockedException(destPath);
if (!processLock.isValid()) throw new FileLockedException(destPath);
destFile = new DiskCacheFile(cacheEntity, destPath, processLock);
if (!cacheFile.renameTo(destFile)) throw new IOException("rename:" + cacheFile.getAbsolutePath());
try {
result = destFile;
this.cacheDb.replace(cacheEntity);
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
this.trimSize();
if (result != null) break block11;
result = cacheFile;
}
catch (InterruptedException ex) {
result = cacheFile;
LogUtil.e(ex.getMessage(), ex);
return result;
}
finally {
if (result == null) {
result = cacheFile;
IOUtil.closeQuietly(destFile);
IOUtil.closeQuietly(processLock);
IOUtil.deleteFileOrDir(destFile);
} else {
IOUtil.closeQuietly(cacheFile);
IOUtil.deleteFileOrDir(cacheFile);
}
}
IOUtil.closeQuietly(destFile);
IOUtil.closeQuietly(processLock);
IOUtil.deleteFileOrDir(destFile);
return result;
}
IOUtil.closeQuietly(cacheFile);
IOUtil.deleteFileOrDir(cacheFile);
return result;
}
private void trimSize() {
this.trimExecutor.execute(new Runnable(){
@Override
public void run() {
if (LruDiskCache.this.available) {
long current = System.currentTimeMillis();
if (current - LruDiskCache.this.lastTrimTime < 1000L) {
return;
}
LruDiskCache.this.lastTrimTime = current;
LruDiskCache.this.deleteExpiry();
try {
Object rmList;
int count = (int)LruDiskCache.this.cacheDb.selector(DiskCacheEntity.class).count();
if (count > 5010 && (rmList = LruDiskCache.this.cacheDb.selector(DiskCacheEntity.class).orderBy("lastAccess").orderBy("hits").limit(count - 5000).offset(0).findAll()) != null && rmList.size() > 0) {
Iterator<DiskCacheEntity> iterator = rmList.iterator();
while (iterator.hasNext()) {
DiskCacheEntity entity = iterator.next();
try {
LruDiskCache.this.cacheDb.delete(entity);
String path = entity.getPath();
if (TextUtils.isEmpty((CharSequence)path)) continue;
LruDiskCache.this.deleteFileWithLock(path);
LruDiskCache.this.deleteFileWithLock(path + LruDiskCache.TEMP_FILE_SUFFIX);
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
try {
while (FileUtil.getFileOrDirSize(LruDiskCache.this.cacheDir) > LruDiskCache.this.diskCacheSize) {
List<DiskCacheEntity> rmList = LruDiskCache.this.cacheDb.selector(DiskCacheEntity.class).orderBy("lastAccess").orderBy("hits").limit(10).offset(0).findAll();
if (rmList == null || rmList.size() <= 0) continue;
for (DiskCacheEntity entity : rmList) {
try {
LruDiskCache.this.cacheDb.delete(entity);
String path = entity.getPath();
if (TextUtils.isEmpty((CharSequence)path)) continue;
LruDiskCache.this.deleteFileWithLock(path);
LruDiskCache.this.deleteFileWithLock(path + LruDiskCache.TEMP_FILE_SUFFIX);
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
}
catch (DbException ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
});
}
private void deleteExpiry() {
try {
WhereBuilder whereBuilder = WhereBuilder.b("expires", "<", System.currentTimeMillis());
List<DiskCacheEntity> rmList = this.cacheDb.selector(DiskCacheEntity.class).where(whereBuilder).findAll();
this.cacheDb.delete(DiskCacheEntity.class, whereBuilder);
if (rmList != null && rmList.size() > 0) {
for (DiskCacheEntity entity : rmList) {
String path = entity.getPath();
if (TextUtils.isEmpty((CharSequence)path)) continue;
this.deleteFileWithLock(path);
}
}
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
private void deleteNoIndexFiles() {
this.trimExecutor.execute(new Runnable(){
@Override
public void run() {
if (LruDiskCache.this.available) {
try {
File[] fileList = LruDiskCache.this.cacheDir.listFiles();
if (fileList != null) {
for (File file : fileList) {
try {
long count = LruDiskCache.this.cacheDb.selector(DiskCacheEntity.class).where("path", "=", file.getAbsolutePath()).count();
if (count >= 1L) continue;
IOUtil.deleteFileOrDir(file);
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
});
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
private boolean deleteFileWithLock(String path) {
ProcessLock processLock = null;
try {
processLock = ProcessLock.tryLock(path, true);
if (processLock != null && processLock.isValid()) {
File file = new File(path);
boolean bl = IOUtil.deleteFileOrDir(file);
return bl;
}
}
finally {
IOUtil.closeQuietly(processLock);
}
return false;
}
}