summaryrefslogtreecommitdiffstats
path: root/gallerycommon/src/com/android/gallery3d/common/FileCache.java
diff options
context:
space:
mode:
Diffstat (limited to 'gallerycommon/src/com/android/gallery3d/common/FileCache.java')
-rw-r--r--gallerycommon/src/com/android/gallery3d/common/FileCache.java312
1 files changed, 0 insertions, 312 deletions
diff --git a/gallerycommon/src/com/android/gallery3d/common/FileCache.java b/gallerycommon/src/com/android/gallery3d/common/FileCache.java
deleted file mode 100644
index d7deda6fa..000000000
--- a/gallerycommon/src/com/android/gallery3d/common/FileCache.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * 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.android.gallery3d.common;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-import com.android.gallery3d.common.Entry.Table;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-
-public class FileCache implements Closeable {
- private static final int LRU_CAPACITY = 4;
- private static final int MAX_DELETE_COUNT = 16;
-
- private static final String TAG = "FileCache";
- private static final String TABLE_NAME = FileEntry.SCHEMA.getTableName();
- private static final String FILE_PREFIX = "download";
- private static final String FILE_POSTFIX = ".tmp";
-
- private static final String QUERY_WHERE =
- FileEntry.Columns.HASH_CODE + "=? AND " + FileEntry.Columns.CONTENT_URL + "=?";
- private static final String ID_WHERE = FileEntry.Columns.ID + "=?";
- private static final String[] PROJECTION_SIZE_SUM =
- {String.format("sum(%s)", FileEntry.Columns.SIZE)};
- private static final String FREESPACE_PROJECTION[] = {
- FileEntry.Columns.ID, FileEntry.Columns.FILENAME,
- FileEntry.Columns.CONTENT_URL, FileEntry.Columns.SIZE};
- private static final String FREESPACE_ORDER_BY =
- String.format("%s ASC", FileEntry.Columns.LAST_ACCESS);
-
- private final LruCache<String, CacheEntry> mEntryMap =
- new LruCache<String, CacheEntry>(LRU_CAPACITY);
-
- private File mRootDir;
- private long mCapacity;
- private boolean mInitialized = false;
- private long mTotalBytes;
-
- private DatabaseHelper mDbHelper;
-
- public static final class CacheEntry {
- private long id;
- public String contentUrl;
- public File cacheFile;
-
- private CacheEntry(long id, String contentUrl, File cacheFile) {
- this.id = id;
- this.contentUrl = contentUrl;
- this.cacheFile = cacheFile;
- }
- }
-
- public static void deleteFiles(Context context, File rootDir, String dbName) {
- try {
- context.getDatabasePath(dbName).delete();
- File[] files = rootDir.listFiles();
- if (files == null) return;
- for (File file : rootDir.listFiles()) {
- String name = file.getName();
- if (file.isFile() && name.startsWith(FILE_PREFIX)
- && name.endsWith(FILE_POSTFIX)) file.delete();
- }
- } catch (Throwable t) {
- Log.w(TAG, "cannot reset database", t);
- }
- }
-
- public FileCache(Context context, File rootDir, String dbName, long capacity) {
- mRootDir = Utils.checkNotNull(rootDir);
- mCapacity = capacity;
- mDbHelper = new DatabaseHelper(context, dbName);
- }
-
- @Override
- public void close() {
- mDbHelper.close();
- }
-
- public void store(String downloadUrl, File file) {
- if (!mInitialized) initialize();
-
- Utils.assertTrue(file.getParentFile().equals(mRootDir));
- FileEntry entry = new FileEntry();
- entry.hashCode = Utils.crc64Long(downloadUrl);
- entry.contentUrl = downloadUrl;
- entry.filename = file.getName();
- entry.size = file.length();
- entry.lastAccess = System.currentTimeMillis();
- if (entry.size >= mCapacity) {
- file.delete();
- throw new IllegalArgumentException("file too large: " + entry.size);
- }
- synchronized (this) {
- FileEntry original = queryDatabase(downloadUrl);
- if (original != null) {
- file.delete();
- entry.filename = original.filename;
- entry.size = original.size;
- } else {
- mTotalBytes += entry.size;
- }
- FileEntry.SCHEMA.insertOrReplace(
- mDbHelper.getWritableDatabase(), entry);
- if (mTotalBytes > mCapacity) freeSomeSpaceIfNeed(MAX_DELETE_COUNT);
- }
- }
-
- public CacheEntry lookup(String downloadUrl) {
- if (!mInitialized) initialize();
- CacheEntry entry;
- synchronized (mEntryMap) {
- entry = mEntryMap.get(downloadUrl);
- }
-
- if (entry != null) {
- synchronized (this) {
- updateLastAccess(entry.id);
- }
- return entry;
- }
-
- synchronized (this) {
- FileEntry file = queryDatabase(downloadUrl);
- if (file == null) return null;
- entry = new CacheEntry(
- file.id, downloadUrl, new File(mRootDir, file.filename));
- if (!entry.cacheFile.isFile()) { // file has been removed
- try {
- mDbHelper.getWritableDatabase().delete(
- TABLE_NAME, ID_WHERE, new String[] {String.valueOf(file.id)});
- mTotalBytes -= file.size;
- } catch (Throwable t) {
- Log.w(TAG, "cannot delete entry: " + file.filename, t);
- }
- return null;
- }
- synchronized (mEntryMap) {
- mEntryMap.put(downloadUrl, entry);
- }
- return entry;
- }
- }
-
- private FileEntry queryDatabase(String downloadUrl) {
- long hash = Utils.crc64Long(downloadUrl);
- String whereArgs[] = new String[] {String.valueOf(hash), downloadUrl};
- Cursor cursor = mDbHelper.getReadableDatabase().query(TABLE_NAME,
- FileEntry.SCHEMA.getProjection(),
- QUERY_WHERE, whereArgs, null, null, null);
- try {
- if (!cursor.moveToNext()) return null;
- FileEntry entry = new FileEntry();
- FileEntry.SCHEMA.cursorToObject(cursor, entry);
- updateLastAccess(entry.id);
- return entry;
- } finally {
- cursor.close();
- }
- }
-
- private void updateLastAccess(long id) {
- ContentValues values = new ContentValues();
- values.put(FileEntry.Columns.LAST_ACCESS, System.currentTimeMillis());
- mDbHelper.getWritableDatabase().update(TABLE_NAME,
- values, ID_WHERE, new String[] {String.valueOf(id)});
- }
-
- public File createFile() throws IOException {
- return File.createTempFile(FILE_PREFIX, FILE_POSTFIX, mRootDir);
- }
-
- private synchronized void initialize() {
- if (mInitialized) return;
-
- if (!mRootDir.isDirectory()) {
- mRootDir.mkdirs();
- if (!mRootDir.isDirectory()) {
- throw new RuntimeException("cannot create: " + mRootDir.getAbsolutePath());
- }
- }
-
- Cursor cursor = mDbHelper.getReadableDatabase().query(
- TABLE_NAME, PROJECTION_SIZE_SUM,
- null, null, null, null, null);
- try {
- if (cursor.moveToNext()) mTotalBytes = cursor.getLong(0);
- } finally {
- cursor.close();
- }
- if (mTotalBytes > mCapacity) freeSomeSpaceIfNeed(MAX_DELETE_COUNT);
-
- // Mark initialized when everything above went through. If an exception was thrown,
- // initialize() will be retried later.
- mInitialized = true;
- }
-
- private void freeSomeSpaceIfNeed(int maxDeleteFileCount) {
- Cursor cursor = mDbHelper.getReadableDatabase().query(
- TABLE_NAME, FREESPACE_PROJECTION,
- null, null, null, null, FREESPACE_ORDER_BY);
- try {
- while (maxDeleteFileCount > 0
- && mTotalBytes > mCapacity && cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String path = cursor.getString(1);
- String url = cursor.getString(2);
- long size = cursor.getLong(3);
-
- synchronized (mEntryMap) {
- // if some one still uses it
- if (mEntryMap.containsKey(url)) continue;
- }
-
- --maxDeleteFileCount;
- if (new File(mRootDir, path).delete()) {
- mTotalBytes -= size;
- mDbHelper.getWritableDatabase().delete(TABLE_NAME,
- ID_WHERE, new String[]{String.valueOf(id)});
- } else {
- Log.w(TAG, "unable to delete file: " + path);
- }
- }
- } finally {
- cursor.close();
- }
- }
-
- @Table("files")
- private static class FileEntry extends Entry {
- public static final EntrySchema SCHEMA = new EntrySchema(FileEntry.class);
-
- public interface Columns extends Entry.Columns {
- public static final String HASH_CODE = "hash_code";
- public static final String CONTENT_URL = "content_url";
- public static final String FILENAME = "filename";
- public static final String SIZE = "size";
- public static final String LAST_ACCESS = "last_access";
- }
-
- @Column(value = Columns.HASH_CODE, indexed = true)
- public long hashCode;
-
- @Column(Columns.CONTENT_URL)
- public String contentUrl;
-
- @Column(Columns.FILENAME)
- public String filename;
-
- @Column(Columns.SIZE)
- public long size;
-
- @Column(value = Columns.LAST_ACCESS, indexed = true)
- public long lastAccess;
-
- @Override
- public String toString() {
- return new StringBuilder()
- .append("hash_code: ").append(hashCode).append(", ")
- .append("content_url").append(contentUrl).append(", ")
- .append("last_access").append(lastAccess).append(", ")
- .append("filename").append(filename).toString();
- }
- }
-
- private final class DatabaseHelper extends SQLiteOpenHelper {
- public static final int DATABASE_VERSION = 1;
-
- public DatabaseHelper(Context context, String dbName) {
- super(context, dbName, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- FileEntry.SCHEMA.createTables(db);
-
- // delete old files
- for (File file : mRootDir.listFiles()) {
- if (!file.delete()) {
- Log.w(TAG, "fail to remove: " + file.getAbsolutePath());
- }
- }
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- //reset everything
- FileEntry.SCHEMA.dropTables(db);
- onCreate(db);
- }
- }
-}