Commit 25cdc61c authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan
Browse files

nfs: use google's guava ComputingMap as direcotry listing cache

Acked-by: Gerd Behrmann
parent 3f312f28
......@@ -17,6 +17,7 @@
package org.dcache.chimera.nfs.v3;
import com.google.common.collect.MapMaker;
import org.dcache.chimera.nfs.vfs.Inode;
import org.dcache.chimera.nfs.v3.xdr.LOOKUP3res;
import org.dcache.chimera.nfs.v3.xdr.WRITE3resfail;
......@@ -125,6 +126,8 @@ import org.dcache.chimera.nfs.v3.xdr.FSINFO3resfail;
import org.dcache.chimera.nfs.v3.xdr.ACCESS3res;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.dcache.chimera.ChimeraFsException;
import org.dcache.chimera.FileNotFoundHimeraFsException;
......@@ -147,7 +150,6 @@ import org.dcache.chimera.posix.Stat;
import org.dcache.chimera.posix.UnixAcl;
import org.dcache.chimera.posix.UnixPermissionHandler;
import org.dcache.chimera.posix.UnixUser;
import org.dcache.chimera.util.DirectoryListCache;
import org.dcache.utils.Bytes;
import org.dcache.xdr.OncRpcException;
import org.dcache.xdr.RpcCall;
......@@ -168,13 +170,13 @@ public class NfsServerV3 extends nfs3_protServerStub {
private static final AclHandler _permissionHandler = UnixPermissionHandler.getInstance();
private final VirtualFileSystem _fs;
private final ExportFile _exports;
private static final DirectoryListCache<InodeCacheEntry<cookieverf3>, List<DirectoryEntry>> _dlCacheFull =
new DirectoryListCache<InodeCacheEntry<cookieverf3>, List<DirectoryEntry>>();
/**
* for each 100 entries cache lifetime will be increased by 1 second
*/
private final static int READDIR_CACHE_FACTOR = 100;
private static final ConcurrentMap<InodeCacheEntry<cookieverf3>, List<DirectoryEntry>> _dlCacheFull =
new MapMaker()
.expireAfterAccess(10, TimeUnit.MINUTES)
.softValues()
.maximumSize(512)
.makeMap();
public NfsServerV3(ExportFile exports, VirtualFileSystem fs) throws OncRpcException, IOException {
_fs = fs;
......@@ -912,7 +914,7 @@ public class NfsServerV3 extends nfs3_protServerStub {
if (dirList == null) {
_log.debug("updating dirlist from db");
dirList = _fs.list(dir);
_dlCacheFull.add(cacheKey, dirList, dirList.size() / READDIR_CACHE_FACTOR);
_dlCacheFull.put(cacheKey, dirList);
} else {
_log.debug("using dirlist from cache");
}
......@@ -1062,7 +1064,7 @@ public class NfsServerV3 extends nfs3_protServerStub {
if (dirList == null) {
_log.debug("updating dirlist from db");
dirList = _fs.list(dir);
_dlCacheFull.add(cacheKey, dirList, dirList.size() / READDIR_CACHE_FACTOR);
_dlCacheFull.put(cacheKey, dirList);
} else {
_log.debug("using dirlist from cache");
}
......
......@@ -18,7 +18,10 @@
package org.dcache.chimera.nfs.v4;
import java.io.IOException;
import com.google.common.collect.MapMaker;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.dcache.chimera.nfs.v4.xdr.nfsstat4;
import org.dcache.chimera.nfs.v4.xdr.entry4;
import org.dcache.chimera.nfs.v4.xdr.dirlist4;
......@@ -42,7 +45,6 @@ import org.dcache.chimera.nfs.vfs.Inode;
import org.dcache.chimera.posix.AclHandler;
import org.dcache.chimera.posix.Stat;
import org.dcache.chimera.posix.UnixAcl;
import org.dcache.chimera.util.DirectoryListCache;
import org.dcache.utils.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -88,15 +90,12 @@ public class OperationREADDIR extends AbstractNFSv4Operation {
private static final int DIRLIST4_SIZE = 4 + nfs4_prot.NFS4_VERIFIER_SIZE + 4 + ENTRY4_SIZE + 4;
private static final int READDIR4RESOK_SIZE = DIRLIST4_SIZE + ENTRY4_SIZE;
private static final DirectoryListCache<InodeCacheEntry<verifier4>,List<DirectoryEntry>> _dlCache =
new DirectoryListCache<InodeCacheEntry<verifier4>, List<DirectoryEntry>>();
/**
* for each 100 entries cache lifetime will be increased by 1 second
*/
private final static int READDIR_CACHE_FACTOR = 100;
private static final ConcurrentMap<InodeCacheEntry<verifier4>,List<DirectoryEntry>> _dlCache =
new MapMaker()
.expireAfterAccess(10, TimeUnit.MINUTES)
.softValues()
.maximumSize(512)
.makeMap();
OperationREADDIR(nfs_argop4 args) {
super(args, nfs_opnum4.OP_READDIR);
}
......@@ -168,8 +167,11 @@ public class OperationREADDIR extends AbstractNFSv4Operation {
if (dirList == null) {
_log.debug("No cached list found for {}", dir);
dirList = context.getFs().list(dir);
_dlCache.add(cacheKey, dirList, dirList.size() / READDIR_CACHE_FACTOR);
_dlCache.put(cacheKey, dirList);
}else {
_log.debug("Cached list found for {}", dir);
}
// the cookie==1,2 is reserved
if( (startValue > dirList.size()+COOKIE_OFFSET) || (startValue < COOKIE_OFFSET) ) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment