[glib/faster-contenttype-guess] xdgmime: Use memmem when we can



commit 0917506dcf843333301d130a264f5b95052b2171
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Oct 15 11:56:16 2019 -0400

    xdgmime: Use memmem when we can
    
    When comparing magic without a mask, we can use
    the optimized function that glibc has for this
    purpose.
    
    This makes g_content_type_guess drop from 10%
    to 3% in some of my GTK profiles. Still not
    ideal. It would be much better if we could
    ask 'Which of these 3 types is it?' style
    questions.

 gio/xdgmime/xdgmimecache.c | 55 +++++++++++++++++++---------------------------
 1 file changed, 23 insertions(+), 32 deletions(-)
---
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
index 769b57836..3150c1cb3 100644
--- a/gio/xdgmime/xdgmimecache.c
+++ b/gio/xdgmime/xdgmimecache.c
@@ -48,6 +48,10 @@
 #include "xdgmimecache.h"
 #include "xdgmimeint.h"
 
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
 #ifndef MAX
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #endif
@@ -175,42 +179,29 @@ cache_magic_matchlet_compare_to_data (XdgMimeCache *cache,
   xdg_uint32_t data_length = GET_UINT32 (cache->buffer, offset + 12);
   xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16);
   xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20);
-  
+  int end;
   int i, j;
+  const unsigned char *_buffer = cache->buffer;
+  const unsigned char *_data = data;
+  
+  if (len < data_length)
+    return FALSE;
 
-  for (i = range_start; i < range_start + range_length; i++)
-    {
-      int valid_matchlet = TRUE;
-      
-      if (i + data_length > len)
-       return FALSE;
+  if (mask_offset == 0)
+    return memmem (_data + range_start, MIN (range_length + data_length, len), _buffer + data_offset, 
data_length) != NULL;
 
-      if (mask_offset)
-       {
-         for (j = 0; j < data_length; j++)
-           {
-             if ((((unsigned char *)cache->buffer)[data_offset + j] & ((unsigned char 
*)cache->buffer)[mask_offset + j]) !=
-                 ((((unsigned char *) data)[j + i]) & ((unsigned char *)cache->buffer)[mask_offset + j]))
-               {
-                 valid_matchlet = FALSE;
-                 break;
-               }
-           }
-       }
-      else
-       {
-         for (j = 0; j < data_length; j++)
-           {
-             if (((unsigned char *)cache->buffer)[data_offset + j] != ((unsigned char *) data)[j + i])
-               {
-                 valid_matchlet = FALSE;
-                 break;
-               }
-           }
+  end = MIN (range_start + range_length, len - data_length);
+
+  for (i = range_start; i < end; i++)
+    {
+      for (j = 0; j < data_length; j++)
+        {
+          if ((_buffer[data_offset + j] & _buffer[mask_offset + j]) !=
+              (_data[i + j] & _buffer[mask_offset + j]))
+            break;
        }
-      
-      if (valid_matchlet)
-       return TRUE;
+      if (j == data_length)
+        return TRUE;
     }
   
   return FALSE;  


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]