Hi,
> I tried to set up a dlna server with an earlier version of vdr-nfofs a few
> months ago. It kinda worked but there were some performance problems in
> regard to file system operations. I hacked a file descriptor cache into the
> python code which helped a bit. Tobi might have included this in the new
> version.
Looks like my patches haven't been accepted for 0.7. You can try my patchset
but I haven't worked on that for some months now. Patch is not minimal and not
cleanly separated, so you should pick the tidbits you like.
Cya, Ed
diff -ur vdrnfofs-0.6/vdrnfofs/concatenated_file_reader.py vdrnfofs-0.6.tyger1//vdrnfofs/concatenated_file_reader.py
--- vdrnfofs-0.6/vdrnfofs/concatenated_file_reader.py 2011-04-14 23:59:21.0 +0200
+++ vdrnfofs-0.6.tyger1//vdrnfofs/concatenated_file_reader.py 2011-04-18 22:35:43.776907385 +0200
@@ -20,32 +20,37 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
+from threading import Lock
+from cStringIO import StringIO
class ConcatenatedFileReader:
def __init__(self, filenames):
self.files = [(f, os.path.getsize(f)) for f in filenames]
self.current_filename = None
self.current_file = None
+self.rwlock = Lock()
def read(self, offset, size):
-buffer = ""
+buffer = StringIO()
ptr = offset
-while (len(buffer) < size):
-(filename, file_offset) = self.filename_from_offset(ptr)
-if filename:
-if (self.current_filename != filename):
-if self.current_file:
-self.current_file.close()
-self.current_filename = filename
-self.current_file = open(filename, 'r')
-self.current_file.seek(file_offset)
-buffer += self.current_file.read(size - len(buffer))
-ptr = offset + len(buffer)
-else:
-break
-return buffer
+with self.rwlock:
+while (buffer.tell() < size):
+(filename, file_offset) = self.filename_from_offset(ptr)
+if filename:
+if (self.current_filename != filename):
+if self.current_file:
+self.current_file.close()
+self.current_filename = filename
+self.current_file = open(filename, 'r')
+self.current_file.seek(file_offset)
+buffer.write(self.current_file.read(size - buffer.tell()))
+ptr = offset + buffer.tell()
+else:
+break
+return buffer.getvalue()
-def release(self):
+def __del__(self):
+# print "CFR::DEL"
if self.current_file:
self.current_file.close()
Only in vdrnfofs-0.6.tyger1//vdrnfofs: concatenated_file_reader.py~
diff -ur vdrnfofs-0.6/vdrnfofs/filesystemnodes.py vdrnfofs-0.6.tyger1//vdrnfofs/filesystemnodes.py
--- vdrnfofs-0.6/vdrnfofs/filesystemnodes.py 2011-04-14 23:27:02.0 +0200
+++ vdrnfofs-0.6.tyger1//vdrnfofs/filesystemnodes.py 2011-04-18 22:39:19.540905997 +0200
@@ -26,6 +26,7 @@
from concatenated_file_reader import *
from vdr import *
+from threading import Lock
class NodeAttributes(fuse.Stat):
def __init__(self):
@@ -40,40 +41,90 @@
self.st_mtime = 0
self.st_ctime = 0
+
class MpgNode:
+cachesize = 20
+cachelock = Lock()
+cache = []
+
+@classmethod
+def create(cls, path, cache):
+if not cache:
+return cls(path)
+with cls.cachelock:
+index = next((i for i in xrange(len(cls.cache)-1, -1, -1) if cls.cache[i].key == path), None)
+if index is not None:
+# print "%s HIT" % cls.__name__
+node = cls.cache.pop(index)
+else:
+# print "%s MISS" % cls.__name__
+node = cls(path)
+if len(cls.cache) > cls.cachesize:
+del cls.cache[0]
+cls.cache.append(node)
+# print "%s cache size: %d" %(cls.__name__, len(cls.cache))
+return node
+
def __init__(self, path):
+# print "MpgNode::init %s" % path
+self.key = path
self.path = os.path.normpath(path)
self.mpeg_files = glob.glob(path + '/[0-9]*.vdr')
if not self.mpeg_files:
self.mpeg_files = glob.glob(path + '/[0-9]*.ts')
self.mpeg_files.sort()
-self.file_system_name = os.path.basename(os.path.abspath(path + '/..')) + '_' + os.path.basename(path) + '.mpg'
+self.file_system_name ="%s_%s.mpg" % (os.path.basename(os.path.abspath(path + '/..')), os.path.basename(path))
self.reader = ConcatenatedFileReader(self.mpeg_files)
-
-def size(self):
size = 0
for file in self.mpeg_files:
size += os.path.getsize(file)
-retur