Code

git: remove $Id$ svn cruft
[fusedav.git] / src / statcache.c
index f71c1a6b4088ff07e559c07d5d5247789cdec26a..28f3e275199d561d2274bcb5e79e0a6b6693f826 100644 (file)
@@ -1,21 +1,25 @@
-/* $Id$ */
-
 /***
-  This file is part of fusedav.
-
-  fusedav is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
-  fusedav is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-  License for more details.
-  
-  You should have received a copy of the GNU General Public License
-  along with fusedav; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+  Copyright (c) 2004-2006 Lennart Poettering
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
 ***/
 
 #ifdef HAVE_CONFIG_H
@@ -31,6 +35,7 @@
 #include <assert.h>
 
 #include "statcache.h"
+#include "filecache.h"
 #include "fusedav.h"
 
 #include <ne_uri.h>
@@ -40,7 +45,6 @@
 
 struct dir_entry {
     struct dir_entry *next;
-    int is_dir;
     char filename[];
 };
 
@@ -70,7 +74,7 @@ static uint32_t calc_hash(const char *s) {
     uint32_t h = 0;
 
     for (; *s; s++) {
-        h ^= * (uint8_t*) s;
+        h ^= * (const uint8_t*) s;
         h = (h << 8) | (h  >> 24);
     }
 
@@ -81,29 +85,36 @@ int stat_cache_get(const char *fn, struct stat *st) {
     uint32_t h;
     struct cache_entry *ce;
     int r = -1;
+    void *f;
 
     if (debug)
         fprintf(stderr, "CGET: %s\n", fn);
-    
+
     assert(cache);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
 
     pthread_mutex_lock(&stat_cache_mutex);
-    
+
     if (ce->stat_info.valid &&
         ce->stat_info.filename &&
         ce->stat_info.hash == h &&
         !strcmp(ce->stat_info.filename, fn) &&
         time(NULL) <= ce->stat_info.dead) {
-        
+
         *st = ce->stat_info.st;
+
+        if ((f = file_cache_get(fn))) {
+            st->st_size = file_cache_get_size(f);
+            file_cache_unref(f);
+        }
+
         r = 0;
     }
 
     pthread_mutex_unlock(&stat_cache_mutex);
-    
+
     return r;
 }
 
@@ -114,7 +125,7 @@ void stat_cache_set(const char *fn, const struct stat*st) {
     if (debug)
         fprintf(stderr, "CSET: %s\n", fn);
     assert(cache);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
 
@@ -125,7 +136,7 @@ void stat_cache_set(const char *fn, const struct stat*st) {
         ce->stat_info.filename = strdup(fn);
         ce->stat_info.hash = h;
     }
-        
+
     ce->stat_info.st = *st;
     ce->stat_info.dead = time(NULL)+CACHE_TIMEOUT;
     ce->stat_info.valid = 1;
@@ -138,7 +149,7 @@ void stat_cache_invalidate(const char*fn) {
     struct cache_entry *ce;
 
     assert(cache);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
 
@@ -147,7 +158,7 @@ void stat_cache_invalidate(const char*fn) {
     ce->stat_info.valid = 0;
     free(ce->stat_info.filename);
     ce->stat_info.filename = NULL;
-    
+
     pthread_mutex_unlock(&stat_cache_mutex);
 }
 
@@ -166,14 +177,14 @@ void dir_cache_begin(const char *fn) {
     struct cache_entry *ce;
     struct dir_entry *de = NULL, *de2 = NULL;
     assert(cache);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
-    
+
     pthread_mutex_lock(&dir_cache_mutex);
 
     if (!ce->dir_info.filling) {
-        
+
         if (!ce->dir_info.filename || ce->dir_info.hash != h || strcmp(ce->dir_info.filename, fn)) {
             free(ce->dir_info.filename);
             ce->dir_info.filename = strdup(fn);
@@ -189,7 +200,7 @@ void dir_cache_begin(const char *fn) {
         ce->dir_info.valid2 = 0;
         ce->dir_info.filling = 1;
     }
-    
+
     pthread_mutex_unlock(&dir_cache_mutex);
     free_dir_entries(de);
     free_dir_entries(de2);
@@ -200,12 +211,12 @@ void dir_cache_finish(const char *fn, int success) {
     struct cache_entry *ce;
     struct dir_entry *de = NULL;
     assert(cache);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
-    
+
     pthread_mutex_lock(&dir_cache_mutex);
-    
+
     if (ce->dir_info.filling &&
         ce->dir_info.filename &&
         ce->dir_info.hash == h &&
@@ -214,11 +225,11 @@ void dir_cache_finish(const char *fn, int success) {
         assert(!ce->dir_info.valid2);
 
         if (success) {
-            
+
             ce->dir_info.valid2 = 1;
             ce->dir_info.filling = 0;
             ce->dir_info.dead2 = time(NULL)+CACHE_TIMEOUT;
-            
+
             if (!ce->dir_info.in_use) {
                 de = ce->dir_info.entries;
                 ce->dir_info.entries = ce->dir_info.entries2;
@@ -227,7 +238,7 @@ void dir_cache_finish(const char *fn, int success) {
                 ce->dir_info.valid2 = 0;
                 ce->dir_info.valid = 1;
             }
-            
+
         } else {
             ce->dir_info.filling = 0;
             de = ce->dir_info.entries2;
@@ -239,16 +250,16 @@ void dir_cache_finish(const char *fn, int success) {
     free_dir_entries(de);
 }
 
-void dir_cache_add(const char *fn, const char *subdir, int is_dir) {
+void dir_cache_add(const char *fn, const char *subdir) {
     uint32_t h;
     struct cache_entry *ce;
     assert(cache);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
-    
+
     pthread_mutex_lock(&dir_cache_mutex);
-    
+
     if (ce->dir_info.filling &&
         ce->dir_info.filename &&
         ce->dir_info.hash == h &&
@@ -262,8 +273,7 @@ void dir_cache_add(const char *fn, const char *subdir, int is_dir) {
         assert(n);
 
         strcpy(n->filename, subdir);
-        n->is_dir = is_dir;
-        
+
         n->next = ce->dir_info.entries2;
         ce->dir_info.entries2 = n;
     }
@@ -271,18 +281,19 @@ void dir_cache_add(const char *fn, const char *subdir, int is_dir) {
     pthread_mutex_unlock(&dir_cache_mutex);
 }
 
-int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *subdir, int is_dir, void *user), void *user) {
+int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *subdir, void *user), void *user) {
     uint32_t h;
     struct cache_entry *ce;
     struct dir_entry *de = NULL;
-    assert(cache && f);
     int r = -1;
-    
+
+    assert(cache && f);
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
-    
+
     pthread_mutex_lock(&dir_cache_mutex);
-    
+
     if (ce->dir_info.valid &&
         ce->dir_info.filename &&
         ce->dir_info.hash == h &&
@@ -293,7 +304,7 @@ int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *su
         pthread_mutex_unlock(&dir_cache_mutex);
 
         for (de = ce->dir_info.entries; de; de = de->next)
-            f(fn, de->filename, de->is_dir, user);
+            f(fn, de->filename, user);
 
         pthread_mutex_lock(&dir_cache_mutex);
         ce->dir_info.in_use = 0;
@@ -309,23 +320,23 @@ int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *su
 
         r = 0;
     }
-    
+
     pthread_mutex_unlock(&dir_cache_mutex);
     free_dir_entries(de);
 
     return r;
-}   
+}
 
 void dir_cache_invalidate(const char*fn) {
     uint32_t h;
     struct cache_entry *ce;
     struct dir_entry *de = NULL;
     assert(cache && fn);
-    
+
     h = calc_hash(fn);
     ce = cache + (h % CACHE_SIZE);
     pthread_mutex_lock(&dir_cache_mutex);
-    
+
     if (ce->dir_info.valid &&
         ce->dir_info.filename &&
         ce->dir_info.hash == h &&
@@ -335,7 +346,7 @@ void dir_cache_invalidate(const char*fn) {
         de = ce->dir_info.entries;
         ce->dir_info.entries = NULL;
     }
-    
+
     pthread_mutex_unlock(&dir_cache_mutex);
     free_dir_entries(de);
 }
@@ -350,7 +361,7 @@ void dir_cache_invalidate_parent(const char *fn) {
             if (p[l-1] == '/')
                 p[l-1] = 0;
         }
-        
+
         dir_cache_invalidate(p);
         free(p);
     } else
@@ -375,11 +386,11 @@ void cache_free(void) {
 }
 
 void cache_alloc(void) {
-    
+
     if (cache)
         return;
 
     cache = malloc(sizeof(struct cache_entry)*CACHE_SIZE);
+    assert(cache);
     memset(cache, 0, sizeof(struct cache_entry)*CACHE_SIZE);
 }
-