Bug 1473113 - Defer initializing the MAR index until it's needed. r=rstrong, a=IanN CLOSED TREE DONTBUILD SEAMONKEY_2_49_ESR_RELBRANCH
authorMatt Howell <mhowell@mozilla.com>
Wed, 11 Jul 2018 10:12:08 -0700
branchSEAMONKEY_2_49_ESR_RELBRANCH
changeset 357534 d43a8a8d75310c964f6115a24b4d416dfaf8a19d
parent 357533 5205eb5a7d31cad2b623be3bbe187066384faf24
child 357535 f8828ed8d6836a04e990eee5330610fe467129ef
push id7834
push userfrgrahl@gmx.net
push dateSun, 13 Jan 2019 12:17:02 +0000
treeherdermozilla-esr52@6e4ad8a8f2e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrstrong, IanN
bugs1473113
milestone52.9.1
Bug 1473113 - Defer initializing the MAR index until it's needed. r=rstrong, a=IanN CLOSED TREE DONTBUILD mozilla-esr52 SEAMONKEY_2_49_ESR_RELBRANCH
modules/libmar/src/mar.h
modules/libmar/src/mar_read.c
--- a/modules/libmar/src/mar.h
+++ b/modules/libmar/src/mar.h
@@ -43,16 +43,17 @@ typedef struct MarItem_ {
   char name[1];           /* file path */
 } MarItem;
 
 #define TABLESIZE 256
 
 struct MarFile_ {
   FILE *fp;
   MarItem *item_table[TABLESIZE];
+  int item_table_is_valid;
 };
 
 typedef struct MarFile_ MarFile;
 
 /**
  * Signature of callback function passed to mar_enum_items.
  * @param mar       The MAR file being visited.
  * @param item      The MAR item being visited.
--- a/modules/libmar/src/mar_read.c
+++ b/modules/libmar/src/mar_read.c
@@ -109,16 +109,17 @@ static int mar_consume_index(MarFile *ma
   return mar_insert_item(mar, name, namelen, offset, length, flags);
 }
 
 static int mar_read_index(MarFile *mar) {
   char id[MAR_ID_SIZE], *buf, *bufptr, *bufend;
   uint32_t offset_to_index, size_of_index;
 
   /* verify MAR ID */
+  fseek(mar->fp, 0, SEEK_SET);
   if (fread(id, MAR_ID_SIZE, 1, mar->fp) != 1)
     return -1;
   if (memcmp(id, MAR_ID, MAR_ID_SIZE) != 0)
     return -1;
 
   if (fread(&offset_to_index, sizeof(uint32_t), 1, mar->fp) != 1)
     return -1;
   offset_to_index = ntohl(offset_to_index);
@@ -155,21 +156,18 @@ static MarFile *mar_fpopen(FILE *fp)
 
   mar = (MarFile *) malloc(sizeof(*mar));
   if (!mar) {
     fclose(fp);
     return NULL;
   }
 
   mar->fp = fp;
+  mar->item_table_is_valid = 0;
   memset(mar->item_table, 0, sizeof(mar->item_table));
-  if (mar_read_index(mar)) {
-    mar_close(mar);
-    return NULL;
-  }
 
   return mar;
 }
 
 MarFile *mar_open(const char *path) {
   FILE *fp;
 
   fp = fopen(path, "rb");
@@ -485,29 +483,45 @@ mar_read_product_info_block(MarFile *mar
   /* If we had a product info block we would have already returned */
   return -1;
 }
 
 const MarItem *mar_find_item(MarFile *mar, const char *name) {
   uint32_t hash;
   const MarItem *item;
 
+  if (!mar->item_table_is_valid) {
+    if (mar_read_index(mar)) {
+      return NULL;
+    } else {
+      mar->item_table_is_valid = 1;
+    }
+  }
+
   hash = mar_hash_name(name);
 
   item = mar->item_table[hash];
   while (item && strcmp(item->name, name) != 0)
     item = item->next;
 
   return item;
 }
 
 int mar_enum_items(MarFile *mar, MarItemCallback callback, void *closure) {
   MarItem *item;
   int i;
 
+  if (!mar->item_table_is_valid) {
+    if (mar_read_index(mar)) {
+      return -1;
+    } else {
+      mar->item_table_is_valid = 1;
+    }
+  }
+
   for (i = 0; i < TABLESIZE; ++i) {
     item = mar->item_table[i];
     while (item) {
       int rv = callback(mar, item, closure);
       if (rv)
         return rv;
       item = item->next;
     }