Imported Upstream version 0.7.5
[platform/upstream/libsolv.git] / src / repopage.c
index 601c5f8..9e9694f 100644 (file)
 #include <fcntl.h>
 #include <time.h>
 
+#ifdef _WIN32
+  #include <windows.h>
+  #include <fileapi.h>
+  #include <io.h>
+#endif
+
 #include "repo.h"
 #include "repopage.h"
 
@@ -45,7 +51,7 @@ typedef uint32_t Ref;
 /*
    The format is tailored for fast decompression (i.e. only byte based),
    and skewed to ASCII content (highest bit often not set):
-   
+
    a 0LLLLLLL
         - self-describing ASCII character hex L
    b 100lllll <l+1 bytes>
@@ -399,7 +405,6 @@ match_done:
              litlen -= 32;
            }
        }
-      litofs = 0;
     }
   return oo;
 }
@@ -591,13 +596,13 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
   else
     {
       /* Quick check in case all pages are already mapped and consecutive.  */
-      for (i = pstart; i <= pend; i++)
-       if (store->mapped_at[i] == -1
-           || (i > pstart
-               && store->mapped_at[i]
-                  != store->mapped_at[i-1] + REPOPAGE_BLOBSIZE))
+      for (pnum = pstart; pnum <= pend; pnum++)
+       if (store->mapped_at[pnum] == -1
+           || (pnum > pstart
+               && store->mapped_at[pnum]
+                  != store->mapped_at[pnum-1] + REPOPAGE_BLOBSIZE))
          break;
-      if (i > pend)
+      if (pnum > pend)
        return store->blob_store + store->mapped_at[pstart];
     }
 
@@ -616,7 +621,8 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
       if (store->nmapped < 4)
         store->nmapped = 4;
       store->mapped = solv_realloc2(store->mapped, store->nmapped, sizeof(store->mapped[0]));
-      memset(store->mapped + oldcan, 0, (store->nmapped - oldcan) * sizeof (store->mapped[0]));
+      for (i = oldcan; i < store->nmapped; i++)
+       store->mapped[i] = -1;
       store->blob_store = solv_realloc2(store->blob_store, store->nmapped, REPOPAGE_BLOBSIZE);
 #ifdef DEBUG_PAGING
       fprintf(stderr, "PAGE: can map %d pages\n", store->nmapped);
@@ -652,15 +658,15 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
     {
       unsigned int pnum_mapped_at;
       unsigned int oldpnum = store->mapped[i];
-      if (oldpnum)
+      if (oldpnum != -1)
        {
-         if (--oldpnum == pnum)
+         if (oldpnum == pnum)
            continue;   /* already have the correct page */
          /* Evict this page.  */
 #ifdef DEBUG_PAGING
          fprintf(stderr, "PAGE: evict page %d from %d\n", oldpnum, i);
 #endif
-         store->mapped[i] = 0;
+         store->mapped[i] = -1;
          store->mapped_at[oldpnum] = -1;
        }
       /* check if we can copy the correct content (before it gets evicted) */
@@ -672,8 +678,8 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
          fprintf(stderr, "PAGECOPY: %d from %d to %d\n", pnum, pnum_mapped_at / REPOPAGE_BLOBSIZE, i);
 #endif
          memcpy(dest, store->blob_store + pnum_mapped_at, REPOPAGE_BLOBSIZE);
-         store->mapped[pnum_mapped_at / REPOPAGE_BLOBSIZE] = 0;        /* slot is now empty */
-         store->mapped[i] = pnum + 1;
+         store->mapped[pnum_mapped_at / REPOPAGE_BLOBSIZE] = -1;
+         store->mapped[i] = pnum;
          store->mapped_at[pnum] = i * REPOPAGE_BLOBSIZE;
        }
     }
@@ -692,7 +698,7 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
 #endif
              /* Still mapped somewhere else, so just copy it from there.  */
              memcpy(dest, store->blob_store + pnum_mapped_at, REPOPAGE_BLOBSIZE);
-             store->mapped[pnum_mapped_at / REPOPAGE_BLOBSIZE] = 0;
+             store->mapped[pnum_mapped_at / REPOPAGE_BLOBSIZE] = -1;
            }
        }
       else
@@ -704,11 +710,22 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
 #ifdef DEBUG_PAGING
          fprintf(stderr, "PAGEIN: %d to %d", pnum, i);
 #endif
+#ifndef _WIN32
           if (pread(store->pagefd, compressed ? buf : dest, in_len, store->file_offset + p->page_offset) != in_len)
            {
              perror("mapping pread");
              return 0;
            }
+#else
+         DWORD read_len;
+         OVERLAPPED ovlp = {0};
+         ovlp.Offset = store->file_offset + p->page_offset;
+         if (!ReadFile((HANDLE) _get_osfhandle(store->pagefd), compressed ? buf : dest, in_len, &read_len, &ovlp) || read_len != in_len)
+         {
+               perror("mapping ReadFile");
+               return 0;
+         }
+#endif
          if (compressed)
            {
              unsigned int out_len;
@@ -729,7 +746,7 @@ repopagestore_load_page_range(Repopagestore *store, unsigned int pstart, unsigne
 #endif
        }
       store->mapped_at[pnum] = i * REPOPAGE_BLOBSIZE;
-      store->mapped[i] = pnum + 1;
+      store->mapped[i] = pnum;
     }
   return store->blob_store + best * REPOPAGE_BLOBSIZE;
 }
@@ -747,15 +764,15 @@ static inline unsigned int
 read_u32(FILE *fp)
 {
   int c, i;
-  unsigned int x = 0; 
+  unsigned int x = 0;
 
-  for (i = 0; i < 4; i++) 
-    {    
+  for (i = 0; i < 4; i++)
+    {
       c = getc(fp);
-      if (c == EOF) 
+      if (c == EOF)
         return 0;
-      x = (x << 8) | c; 
-    }    
+      x = (x << 8) | c;
+    }
   return x;
 }
 
@@ -785,7 +802,7 @@ repopagestore_read_or_setup_pages(Repopagestore *store, FILE *fp, unsigned int p
   if (store->pagefd == -1)
     can_seek = 0;
   else
-    fcntl(store->pagefd, F_SETFD, FD_CLOEXEC);
+    solv_setcloexec(store->pagefd, 1);
 
 #ifdef DEBUG_PAGING
   fprintf(stderr, "can %sseek\n", can_seek ? "" : "NOT ");