大体思路
这其实是一个LRU cache 用
private final Map<String, CacheHeader> mEntries =
new LinkedHashMap<String, CacheHeader>(16, .75f, true);
来维护一个优先队列,在空间满了的时候讲那些队头的删掉,因为
LinkedHashMap的构造函数最后一个参数accessOrder为TRUE,所以每次更改哈希表中的元素都会使这个元素被插入到队尾,容量不足删除的时候获得一个从对头开始的iterator然后开始删除直到空间够了为止。put()的时候会先将Entry的头部信息单独拿出来现写入文件,这个头部信息就是LinkedHashMap中存的信息用于判定文件是否在磁盘缓存中,每次对缓存的更改都会维护这个哈希表。初始化的时候initialize()函数会获得缓存目录中的文件列表,然后到每个文件中区读头部信息加入到hash表中,我觉得这里将hash表单独写入到一个文件中,读的时候会更加高效。//不同的机器求hashcode的实现不同,hash表的序列化也不是直接写入和读出的,也是要在读出的时候在建立hash表
实现细节
private String getFilenameForKey(String key) {
int firstHalfLength = key.length() / 2;
String localFilename = String.valueOf(key.substring(0, firstHalfLength).hashCode());
localFilename += String.valueOf(key.substring(firstHalfLength).hashCode());
return localFilename;
}
缓存中文件的名字是key的前半部分的hashCode和后半部分的hashCode拼起来的。
writeInt(os, CACHE_MAGIC);
int magic = readInt(is);
if (magic != CACHE_MAGIC) {
// don't bother deleting, it'll get pruned eventually
throw new IOException();
}
写入头部的时候会先写入一个特殊的值,如果该读的时候读不到这个值就抛出异常。
static void writeString(OutputStream os, String s) throws IOException {
byte[] b = s.getBytes("UTF-8");
writeLong(os, b.length);
os.write(b, 0, b.length);
}
static String readString(InputStream is) throws IOException {
int n = (int) readLong(is);
byte[] b = streamToBytes(is, n);
return new String(b, "UTF-8");
}
String是如何读写的。