Ticket #325: 23_vfs_no_slist.patch

File 23_vfs_no_slist.patch, 4.4 KB (added by andrew_b, 10 years ago)
  • mc-4.6.2-pre1

    This patch makes VFS a bit faster by replacing GSList with GPtrArray
    and using a clever trick to avoid doing list/array searches on every
    VFS lookup.
    
    Andrew Zabolotny <zap@homelink.ru>
    diff -ur mc-4.6.2-pre1.orig/vfs/fish.c mc-4.6.2-pre1/vfs/fish.c
    old new  
    635635#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 || (defined _LARGE_FILES && _LARGE_FILES) 
    636636    if (sscanf( reply_str, "%llu", &fh->u.fish.total )!=1) 
    637637#else 
    638     if (sscanf( reply_str, "%u", &fh->u.fish.total )!=1) 
     638    if (sscanf (reply_str, "%lu", &fh->u.fish.total) != 1) 
    639639#endif 
    640640        ERRNOR (E_REMOTE, 0); 
    641641    return 1; 
  • mc-4.6.2-pre1

    diff -ur mc-4.6.2-pre1.orig/vfs/vfs.c mc-4.6.2-pre1/vfs/vfs.c
    old new  
    6363    void *fsinfo; 
    6464}; 
    6565 
    66 static GSList *vfs_openfiles; 
     66static GPtrArray *vfs_openfiles; 
     67static long vfs_free_handle_list = -1; 
    6768#define VFS_FIRST_HANDLE 100 
    6869 
    6970static struct vfs_class *localfs_class; 
     
    7273static int 
    7374vfs_new_handle (struct vfs_class *vclass, void *fsinfo) 
    7475{ 
    75     static int vfs_handle_counter = VFS_FIRST_HANDLE; 
    7676    struct vfs_openfile *h; 
    7777 
    7878    h = g_new (struct vfs_openfile, 1); 
    79     h->handle = vfs_handle_counter++; 
    8079    h->fsinfo = fsinfo; 
    8180    h->vclass = vclass; 
    82     vfs_openfiles = g_slist_prepend (vfs_openfiles, h); 
    83     return h->handle; 
    84 } 
    8581 
    86 /* Function to match handle, passed to g_slist_find_custom() */ 
    87 static gint 
    88 vfs_cmp_handle (gconstpointer a, gconstpointer b) 
    89 { 
    90     if (!a) 
    91         return 1; 
    92     return ((struct vfs_openfile *) a)->handle != (long) b; 
     82    /* Allocate the first free handle */ 
     83    h->handle = vfs_free_handle_list; 
     84    if (h->handle == -1) { 
     85        /* No free allocated handles, allocate one */ 
     86        h->handle = vfs_openfiles->len; 
     87        g_ptr_array_add (vfs_openfiles, h); 
     88    } else { 
     89        vfs_free_handle_list = (long) g_ptr_array_index (vfs_openfiles, vfs_free_handle_list); 
     90        g_ptr_array_index (vfs_openfiles, h->handle) = h; 
     91    } 
     92 
     93    h->handle += VFS_FIRST_HANDLE; 
     94    return h->handle; 
    9395} 
    9496 
    9597/* Find VFS class by file handle */ 
    9698static inline struct vfs_class * 
    9799vfs_op (int handle) 
    98100{ 
    99     GSList *l; 
    100101    struct vfs_openfile *h; 
    101102 
    102     l = g_slist_find_custom (vfs_openfiles, (void *) (long) handle, 
    103                              vfs_cmp_handle); 
    104     if (!l) 
    105         return NULL; 
    106     h = (struct vfs_openfile *) l->data; 
     103    if (handle < VFS_FIRST_HANDLE || 
     104        handle - VFS_FIRST_HANDLE >= vfs_openfiles->len) 
     105        return NULL; 
     106 
     107    h = (struct vfs_openfile *) g_ptr_array_index ( 
     108                                vfs_openfiles, handle - VFS_FIRST_HANDLE); 
    107109    if (!h) 
    108         return NULL; 
     110        return NULL; 
     111 
     112    g_assert (h->handle == handle); 
     113 
    109114    return h->vclass; 
    110115} 
    111116 
     
    113118static inline void * 
    114119vfs_info (int handle) 
    115120{ 
    116     GSList *l; 
    117121    struct vfs_openfile *h; 
    118122 
    119     l = g_slist_find_custom (vfs_openfiles, (void *) (long) handle, 
    120                              vfs_cmp_handle); 
    121     if (!l) 
    122         return NULL; 
    123     h = (struct vfs_openfile *) l->data; 
     123    if (handle < VFS_FIRST_HANDLE || 
     124        handle - VFS_FIRST_HANDLE >= vfs_openfiles->len) 
     125        return NULL; 
     126 
     127    h = (struct vfs_openfile *) g_ptr_array_index ( 
     128                                vfs_openfiles, handle - VFS_FIRST_HANDLE); 
    124129    if (!h) 
    125         return NULL; 
     130        return NULL; 
     131 
     132    g_assert (h->handle == handle); 
     133 
    126134    return h->fsinfo; 
    127135} 
    128136 
     
    130138static inline void 
    131139vfs_free_handle (int handle) 
    132140{ 
    133     GSList *l; 
    134  
    135     l = g_slist_find_custom (vfs_openfiles, (void *) (long) handle, 
    136                              vfs_cmp_handle); 
    137     vfs_openfiles = g_slist_delete_link (vfs_openfiles, l); 
     141    if (handle < VFS_FIRST_HANDLE || 
     142        handle - VFS_FIRST_HANDLE >= vfs_openfiles->len) 
     143        return; 
     144 
     145    g_ptr_array_index (vfs_openfiles, handle - VFS_FIRST_HANDLE) = 
     146                        (void *) vfs_free_handle_list; 
     147    vfs_free_handle_list = handle - VFS_FIRST_HANDLE; 
    138148} 
    139149 
    140150static struct vfs_class *vfs_list; 
     
    867877void 
    868878vfs_init (void) 
    869879{ 
     880    /* create the VFS handle array */ 
     881    vfs_openfiles = g_ptr_array_new (); 
     882 
    870883    /* localfs needs to be the first one */ 
    871884    init_localfs(); 
    872885    /* fallback value for vfs_get_class() */ 
     
    909922        if (vfs->done) 
    910923            (*vfs->done) (vfs); 
    911924 
    912     g_slist_free (vfs_openfiles); 
     925    g_ptr_array_free (vfs_openfiles, TRUE); 
    913926} 
    914927 
    915928/*