Kirill K. Smirnov : winhelp: Rewrite Context support using B+ tree search.

Alexandre Julliard julliard at winehq.org
Mon Dec 3 09:17:58 CST 2007


Module: wine
Branch: master
Commit: f4023569b3cfcd5f29bedabf29ed8eb0e7ccca5b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f4023569b3cfcd5f29bedabf29ed8eb0e7ccca5b

Author: Kirill K. Smirnov <lich at math.spbu.ru>
Date:   Sat Dec  1 19:01:25 2007 +0300

winhelp: Rewrite Context support using B+ tree search.

---

 programs/winhelp/hlpfile.c |  100 ++++++++++++-------------------------------
 programs/winhelp/hlpfile.h |    9 +----
 2 files changed, 29 insertions(+), 80 deletions(-)

diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c
index af86690..27d5555 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -161,13 +161,32 @@ HLPFILE_PAGE *HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset)
     return found;
 }
 
+/**************************************************************************
+ * comp_PageByHash
+ *
+ * HLPFILE_BPTreeCompare function for '|CONTEXT' B+ tree file
+ *
+ */
+static int comp_PageByHash(void *p, const void *key,
+                           int leaf, void** next)
+{
+    LONG lKey = (LONG)key;
+    LONG lTest = GET_UINT(p, 0);
+
+    *next = (char *)p+(leaf?8:6);
+    WINE_TRACE("Comparing '%u' with '%u'\n", lKey, lTest);
+    if (lTest < lKey) return -1;
+    if (lTest > lKey) return 1;
+    return 0;
+}
+
 /***********************************************************************
  *
  *           HLPFILE_HlpFilePageByHash
  */
 HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
 {
-    unsigned int i;
+    BYTE *ptr;
 
     if (!hlpfile) return 0;
 
@@ -177,14 +196,14 @@ HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash)
     if (hlpfile->version <= 16)
         return HLPFILE_PageByNumber(hlpfile, lHash);
 
-    for (i = 0; i < hlpfile->wContextLen; i++)
+    ptr = HLPFILE_BPTreeSearch(hlpfile->Context, (void*)lHash, comp_PageByHash);
+    if (!ptr)
     {
-        if (hlpfile->Context[i].lHash == lHash)
-            return HLPFILE_PageByOffset(hlpfile, hlpfile->Context[i].offset);
+        WINE_ERR("Page of hash %x not found in file %s\n", lHash, hlpfile->lpszPath);
+        return NULL;
     }
 
-    WINE_ERR("Page of hash %x not found in file %s\n", lHash, hlpfile->lpszPath);
-    return NULL;
+    return HLPFILE_PageByOffset(hlpfile, GET_UINT(ptr, 4));
 }
 
 /***********************************************************************
@@ -272,7 +291,6 @@ HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath)
     hlpfile->lpszCopyright      = NULL;
     hlpfile->first_page         = NULL;
     hlpfile->first_macro        = NULL;
-    hlpfile->wContextLen        = 0;
     hlpfile->Context            = NULL;
     hlpfile->wMapLen            = 0;
     hlpfile->Map                = NULL;
@@ -1978,63 +1996,6 @@ static void* HLPFILE_BPTreeSearch(BYTE* buf, const void* key,
     return NULL;
 }
 
-/******************************************************************
- *		HLPFILE_EnumBTreeLeaves
- *
- *
- */
-static void HLPFILE_EnumBTreeLeaves(const BYTE* buf, const BYTE* end, unsigned (*fn)(const BYTE*, void*), void* user)
-{
-    unsigned    psize, pnext;
-    unsigned    num, nlvl;
-    const BYTE* ptr;
-
-    num    = GET_UINT(buf, 9 + 34);
-    psize  = GET_USHORT(buf, 9 + 4);
-    nlvl   = GET_USHORT(buf, 9 + 32);
-    pnext  = GET_USHORT(buf, 9 + 26);
-
-    WINE_TRACE("BTree: #entries=%u pagSize=%u #levels=%u #pages=%u root=%u struct%16s\n",
-               num, psize, nlvl, GET_USHORT(buf, 9 + 30), pnext, buf + 9 + 6);
-    if (!num) return;
-
-    while (--nlvl > 0)
-    {
-        ptr = (buf + 9 + 38) + pnext * psize;
-        WINE_TRACE("BTree: (index[%u]) unused=%u #entries=%u <%u\n",
-                   pnext, GET_USHORT(ptr, 0), GET_USHORT(ptr, 2), GET_USHORT(ptr, 4));
-        pnext = GET_USHORT(ptr, 4);
-    }
-    while (pnext != 0xFFFF)
-    {
-        const BYTE*     node_page;
-        unsigned short  limit;
-
-        node_page = ptr = (buf + 9 + 38) + pnext * psize;
-        limit = GET_USHORT(ptr, 2);
-        WINE_TRACE("BTree: (leaf [%u]) unused=%u #entries=%u <%u >%u\n",
-                   pnext, GET_USHORT(ptr, 0), limit, GET_USHORT(ptr, 4), GET_USHORT(ptr, 6));
-        ptr += 8;
-        while (limit--)
-            ptr += (fn)(ptr, user);
-        pnext = GET_USHORT(node_page, 6);
-    }
-}
-
-struct myfncb {
-    HLPFILE*    hlpfile;
-    int         i;
-};
-
-static unsigned myfn(const BYTE* ptr, void* user)
-{
-    struct myfncb*      m = user;
-
-    m->hlpfile->Context[m->i].lHash  = GET_UINT(ptr, 0);
-    m->hlpfile->Context[m->i].offset = GET_UINT(ptr, 4);
-    m->i++;
-    return 8;
-}
 
 /***********************************************************************
  *
@@ -2043,19 +2004,14 @@ static unsigned myfn(const BYTE* ptr, void* user)
 static BOOL HLPFILE_GetContext(HLPFILE *hlpfile)
 {
     BYTE                *cbuf, *cend;
-    struct myfncb       m;
     unsigned            clen;
 
     if (!HLPFILE_FindSubFile("|CONTEXT",  &cbuf, &cend)) {WINE_WARN("context0\n"); return FALSE;}
 
-    clen = GET_UINT(cbuf, 0x2b);
-    hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen * sizeof(HLPFILE_CONTEXT));
+    clen = cend - cbuf;
+    hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen);
     if (!hlpfile->Context) return FALSE;
-    hlpfile->wContextLen = clen;
-
-    m.hlpfile = hlpfile;
-    m.i = 0;
-    HLPFILE_EnumBTreeLeaves(cbuf, cend, myfn, &m);
+    memcpy(hlpfile->Context, cbuf, clen);
 
     return TRUE;
 }
diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h
index 3c6b6b9..69cd604 100644
--- a/programs/winhelp/hlpfile.h
+++ b/programs/winhelp/hlpfile.h
@@ -104,12 +104,6 @@ typedef struct tagHlpFilePage
 
 typedef struct
 {
-    LONG                        lHash;
-    unsigned long               offset;
-} HLPFILE_CONTEXT;
-
-typedef struct
-{
     LONG                        lMap;
     unsigned long               offset;
 } HLPFILE_MAP;
@@ -128,8 +122,7 @@ typedef struct tagHlpFileFile
     LPSTR                       lpszCopyright;
     HLPFILE_PAGE*               first_page;
     HLPFILE_MACRO*              first_macro;
-    unsigned                    wContextLen;
-    HLPFILE_CONTEXT*            Context;
+    BYTE*                       Context;
     unsigned                    wMapLen;
     HLPFILE_MAP*                Map;
     unsigned long               contents_start;




More information about the wine-cvs mailing list