Browse Source

HPCC-23428 Avoid the need to backpatch indexes

Fixes following testing

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 5 years ago
parent
commit
ca8ad098c5
4 changed files with 40 additions and 12 deletions
  1. 27 8
      system/jhtree/ctfile.cpp
  2. 2 3
      system/jhtree/ctfile.hpp
  3. 1 1
      tools/dumpkey/dumpkey.cpp
  4. 10 0
      tools/vkey/vkey.cpp

+ 27 - 8
system/jhtree/ctfile.cpp

@@ -106,13 +106,22 @@ extern bool isCompressedIndex(const char *filename)
         if (io->read(0, sizeof(hdr), &hdr) == sizeof(hdr))
         {
             SwapBigEndian(hdr);
-            if (size % hdr.nodeSize == 0 && hdr.phyrec == size-1 && hdr.root && hdr.root % hdr.nodeSize == 0 && hdr.ktype & (HTREE_COMPRESSED_KEY|HTREE_QUICK_COMPRESSED_KEY))
+            if (size % hdr.nodeSize == 0 && hdr.phyrec == size-1 && hdr.ktype & (HTREE_COMPRESSED_KEY|HTREE_QUICK_COMPRESSED_KEY))
             {
-                NodeHdr root;
-                if (io->read(hdr.root, sizeof(root), &root) == sizeof(root))
+                if (hdr.ktype & USE_TRAILING_HEADER)
                 {
-                    SwapBigEndian(root);
-                    return root.leftSib==0 && root.rightSib==0; 
+                    if (io->read(size-hdr.nodeSize, sizeof(hdr), &hdr) != sizeof(hdr))
+                        return false;
+                    SwapBigEndian(hdr);
+                }
+                if (size % hdr.nodeSize == 0 && hdr.phyrec == size-1 && hdr.root && hdr.root % hdr.nodeSize == 0 && hdr.ktype & (HTREE_COMPRESSED_KEY|HTREE_QUICK_COMPRESSED_KEY))
+                {
+                    NodeHdr root;
+                    if (io->read(hdr.root, sizeof(root), &root) == sizeof(root))
+                    {
+                        SwapBigEndian(root);
+                        return root.leftSib==0 && root.rightSib==0;
+                    }
                 }
             }
         }
@@ -134,9 +143,19 @@ extern jhtree_decl bool isIndexFile(IFile *file)
         if (io->read(0, sizeof(hdr), &hdr) != sizeof(hdr))
             return false;
         SwapBigEndian(hdr);
-        if (!hdr.root || !hdr.nodeSize || !hdr.root || size % hdr.nodeSize || hdr.root % hdr.nodeSize || hdr.root >= size)
-            return false;
-        return true;    // Reasonable heuristic...
+        if (size % hdr.nodeSize == 0 && hdr.phyrec == size-1)
+        {
+            if (hdr.ktype & USE_TRAILING_HEADER)
+            {
+                if (io->read(size-hdr.nodeSize, sizeof(hdr), &hdr) != sizeof(hdr))
+                    return false;
+                SwapBigEndian(hdr);
+
+            }
+            if (!hdr.root || !hdr.nodeSize || !hdr.root || size % hdr.nodeSize || hdr.root % hdr.nodeSize || hdr.root >= size)
+                return false;
+            return true;    // Reasonable heuristic...
+        }
     }
     catch (IException *E)
     {

+ 2 - 3
system/jhtree/ctfile.hpp

@@ -27,11 +27,10 @@
 
 #define NODESIZE 8192
 
-
-#define HTREE_FPOS_OFFSET   0x01 // Obsolete, not supported
+#define TRAILING_HEADER_ONLY  0x01 // Leading header not updated - use trailing one
 #define HTREE_TOPLEVEL_KEY  0x02
 #define COL_PREFIX          0x04
-#define TRAILING_HEADER_ONLY  0x08 // Leading header not updated - use trailing one
+#define HTREE_QUICK_COMPRESSED 0x08 // See QUICK_COMPRESSED_KEY below
 #define HTREE_VARSIZE       0x10
 #define HTREE_FULLSORT_KEY  0x20
 #define USE_TRAILING_HEADER  0x80 // Real index header node located at end of file

+ 1 - 1
tools/dumpkey/dumpkey.cpp

@@ -227,7 +227,7 @@ int main(int argc, const char **argv)
                         E->Release();
                     }
                 }
-                if (!diskmeta && metadata->hasProp("_record_ECL"))
+                if (!diskmeta && metadata && metadata->hasProp("_record_ECL"))
                 {
                     MultiErrorReceiver errs;
                     Owned<IHqlExpression> expr = parseQuery(metadata->queryProp("_record_ECL"), &errs);

+ 10 - 0
tools/vkey/vkey.cpp

@@ -406,6 +406,16 @@ int main(int argc, const char *argv[])
                 else
                 {
                     SwapBigEndian(h);
+                    if (h.ktype & USE_TRAILING_HEADER)
+                    {
+                        printf("Reading trailing key header\n");
+                        lseek(f, -h.nodeSize, SEEK_END);
+                        if (_read(f, &h, sizeof(h)) != sizeof(h))
+                        {
+                            noteError(0, "Could not read trailing key header\n");
+                        }
+                        SwapBigEndian(h);
+                    }
                     if (nodeAddress)
                     {
                         checkNode(f, h, nodeAddress);