用于缓存文件夹和文件的高效数据结构

时间:2011-11-23 12:07:45

标签: java google-app-engine caching

我们有一个服务层,如下所示

interface StructureService {
    void create(FileEntry entry, EntryType type) throws IOException;
    Collection<FileEntry> getChildren(FileEntry entry)  throws IOException;
    void delete(FileEntry entry) throws IOException;
    void rename(FileEntry file, FileEntry newFile) throws IOException;
    void copy(FileEntry source, FileEntry destination) throws IOException;
    EntryType getType(FileEntry entry);
    long getLastModified(FileEntry entry) throws IOException;
    long getSize(FileEntry entry) throws IOException;
}

我们已经创建了一个用于缓存这些服务的代理,因为数据源可能来自数据库或rpc调用。

目前,缓存实现会清除整个缓存并在修改操作后重建它。这导致竞争条件可以通过同步呼叫来解决。然而,这是非常低效的。

相反,我们想修改每个操作的结构。

我想知道是否有一个好的,最好少锁定的已知java实现可以帮助解决这个问题。

我们在谷歌应用引擎上使用memcache作为后端,因此存储每个条目与键值对可能有所帮助。

1 个答案:

答案 0 :(得分:1)

如果您的结构是文件夹/文件树,请尝试从根到叶子获取锁定,然后执行您的操作。对每个项目使用ReadAndWriteLock。

如果您正在阅读使用readlock。如果您正在为父母编写使用读锁定,除了中间父项和项目本身。使用它们使用写锁定。

当您获得某些内容获取锁定(必要时创建它)时,抓取数据(如果不在缓存中则读取数据),执行操作并释放锁定。

类树状锁获取父项的读锁,只有被修改项的写锁可以让你进行并发访问,但在修改时可以正确锁定。

<强>样品

更新/ a / b / c / d

lock for a - grab read lock
lock for b - grab read lock
lock for c - gran read lock
lock for d - grab write lock

创建/删除/ a / b / c / d

lock for a - grab read lock
lock for b - grab read lock
lock for c - gran **write** lock // you are modifying c's list of files

list / a / b / c / d

lock for a - grab read lock
lock for b - grab read lock
lock for c - gran read lock
lock for d - grab read lock

注意

我真的不知道在GAE中实现这一点的最佳方法是什么。如果您为每个项目都有唯一的锁,它就可以工作。在GAE案例中......我不知道你是否可以拥有它。