[Groonga-commit] groonga/groonga at c3c5c11 [master] windows io: support small start file size like UNIX like environment

Back to archive index

Kouhei Sutou null+****@clear*****
Sat Jan 17 16:13:41 JST 2015


Kouhei Sutou	2015-01-17 16:13:41 +0900 (Sat, 17 Jan 2015)

  New Revision: c3c5c11b9aa904ba5545915130c1e1bb2b2fc67e
  https://github.com/groonga/groonga/commit/c3c5c11b9aa904ba5545915130c1e1bb2b2fc67e

  Message:
    windows io: support small start file size like UNIX like environment

  Modified files:
    lib/io.c

  Modified: lib/io.c (+280 -187)
===================================================================
--- lib/io.c    2015-01-17 16:09:14 +0900 (7743ed6)
+++ lib/io.c    2015-01-17 16:13:41 +0900 (812199d)
@@ -30,14 +30,14 @@
 
 #define GRN_IO_IDSTR "GROONGA:IO:00001"
 
+#define GRN_IO_VERSION_DEFAULT 0
+
+#define GRN_IO_FILE_SIZE_V1 1073741824UL
+
 #ifdef WIN32
-# ifdef WIN32_FMO_EACH
-#  define GRN_IO_FILE_SIZE  1073741824UL
-# else /* FMO_EACH */
-#  define GRN_IO_FILE_SIZE  134217728L
-# endif /* FMO_EACH */
+# define GRN_IO_FILE_SIZE_V0  134217728L
 #else /* WIN32 */
-# define GRN_IO_FILE_SIZE  1073741824UL
+# define GRN_IO_FILE_SIZE_V0  GRN_IO_FILE_SIZE_V1
 #endif /* WIN32 */
 
 #ifndef O_BINARY
@@ -62,31 +62,42 @@ typedef struct _grn_io_fileinfo {
 
 #define IO_HEADER_SIZE 64
 
+static uint32_t grn_io_version_default = GRN_IO_VERSION_DEFAULT;
+
 inline static grn_rc grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags);
 inline static void grn_fileinfo_init(fileinfo *fis, int nfis);
 inline static int grn_opened(fileinfo *fi);
 inline static grn_rc grn_close(grn_ctx *ctx, fileinfo *fi);
-#if defined(WIN32) && defined(WIN32_FMO_EACH)
-inline static void * grn_mmap(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi,
+#ifdef WIN32
+inline static void * grn_mmap(grn_ctx *ctx, grn_io *io,
+                              HANDLE *fmo, fileinfo *fi,
                               off_t offset, size_t length);
-inline static int grn_munmap(grn_ctx *ctx, HANDLE *fmo, void *start, size_t length);
-#define GRN_MMAP(ctx,fmo,fi,offset,length)\
-  (grn_mmap((ctx), (fmo), (fi), (offset), (length)))
-#define GRN_MUNMAP(ctx,fmo,start,length) (grn_munmap((ctx), (fmo), (start), (length)))
-#else /* defined(WIN32) && defined(WIN32_FMO_EACH) */
-inline static void * grn_mmap(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length);
-inline static int grn_munmap(grn_ctx *ctx, void *start, size_t length);
-#define GRN_MUNMAP(ctx,fmo,start,length) (grn_munmap((ctx), (start), (length)))
-#ifdef USE_FAIL_MALLOC
-inline static void * grn_fail_mmap(grn_ctx *ctx, fileinfo *fi,
+inline static int grn_munmap(grn_ctx *ctx, grn_io *io,
+                             HANDLE *fmo, fileinfo *fi,
+                             void *start, size_t length);
+# define GRN_MMAP(ctx,io,fmo,fi,offset,length)\
+  (grn_mmap((ctx), (io), (fmo), (fi), (offset), (length)))
+# define GRN_MUNMAP(ctx,io,fmo,fi,start,length)\
+  (grn_munmap((ctx), (io), (fmo), (fi), (start), (length)))
+#else /* WIN32 */
+inline static void * grn_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+                              off_t offset, size_t length);
+inline static int grn_munmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+                             void *start, size_t length);
+# define GRN_MUNMAP(ctx,io,fmo,fi,start,length) \
+  (grn_munmap((ctx), (io), (fi), (start), (length)))
+# ifdef USE_FAIL_MALLOC
+inline static void * grn_fail_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
                                    off_t offset, size_t length,
                                    const char* file, int line, const char *func);
-#define GRN_MMAP(ctx,fmo,fi,offset,length)                              \
-  (grn_fail_mmap((ctx), (fi), (offset), (length), __FILE__, __LINE__, __FUNCTION__))
-#else /* USE_FAIL_MALLOC */
-#define GRN_MMAP(ctx,fmo,fi,offset,length) (grn_mmap((ctx), (fi), (offset), (length)))
-#endif /* USE_FAIL_MALLOC */
-#endif  /* defined(WIN32) && defined(WIN32_FMO_EACH) */
+#  define GRN_MMAP(ctx,io,fmo,fi,offset,length)\
+  (grn_fail_mmap((ctx), (io), (fi), (offset), (length),\
+                 __FILE__, __LINE__, __FUNCTION__))
+# else /* USE_FAIL_MALLOC */
+#  define GRN_MMAP(ctx,io,fmo,fi,offset,length)\
+  (grn_mmap((ctx), (io), (fi), (offset), (length)))
+# endif /* USE_FAIL_MALLOC */
+#endif  /* WIN32 */
 inline static int grn_msync(grn_ctx *ctx, void *start, size_t length);
 inline static grn_rc grn_pread(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset);
 inline static grn_rc grn_pwrite(grn_ctx *ctx, fileinfo *fi, void *buf, size_t count, off_t offset);
@@ -126,6 +137,16 @@ grn_io_compute_max_n_files(uint32_t segment_size, uint32_t max_segment,
   return (uint32_t)((last_segment_end + file_size - 1) / file_size);
 }
 
+static inline unsigned long
+grn_io_compute_file_size(uint32_t version)
+{
+  if (version == 0) {
+    return GRN_IO_FILE_SIZE_V0;
+  } else {
+    return GRN_IO_FILE_SIZE_V1;
+  }
+}
+
 static inline uint32_t
 grn_io_max_segment(grn_io *io)
 {
@@ -139,8 +160,9 @@ grn_io_max_segment(grn_io *io)
 static uint32_t
 grn_io_max_n_files(grn_io *io)
 {
-  unsigned long file_size = GRN_IO_FILE_SIZE;
+  unsigned long file_size;
 
+  file_size = grn_io_compute_file_size(io->header->version);
   return grn_io_compute_max_n_files(io->header->segment_size,
                                     grn_io_max_segment(io),
                                     io->base_seg,
@@ -155,7 +177,9 @@ grn_io_create_tmp(uint32_t header_size, uint32_t segment_size,
   uint32_t b;
   struct _grn_io_header *header;
   b = grn_io_compute_base(header_size);
-  if ((header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, NULL, NULL, 0, b))) {
+  header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, NULL, NULL, NULL, 0, b);
+  if (header) {
+    header->version = grn_io_version_default;
     header->header_size = header_size;
     header->segment_size = segment_size;
     header->max_segment = max_segment;
@@ -185,7 +209,7 @@ grn_io_create_tmp(uint32_t header_size, uint32_t segment_size,
       }
       GRN_GFREE(io);
     }
-    GRN_MUNMAP(&grn_gctx, NULL, header, b);
+    GRN_MUNMAP(&grn_gctx, NULL, NULL, NULL, header, b);
   }
   return NULL;
 }
@@ -237,18 +261,25 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
   uint32_t b, max_nfiles;
   uint32_t bs;
   struct _grn_io_header *header;
+  uint32_t version = grn_io_version_default;
+  unsigned long file_size;
+
   if (!path) {
     return grn_io_create_tmp(header_size, segment_size, max_segment, mode, flags);
   }
   if (!*path || (strlen(path) > PATH_MAX - 4)) { return NULL; }
   b = grn_io_compute_base(header_size);
   bs = grn_io_compute_base_segment(b, segment_size);
+  file_size = grn_io_compute_file_size(version);
   max_nfiles = grn_io_compute_max_n_files(segment_size, max_segment,
-                                          bs, GRN_IO_FILE_SIZE);
+                                          bs, file_size);
   if ((fis = GRN_GMALLOCN(fileinfo, max_nfiles))) {
     grn_fileinfo_init(fis, max_nfiles);
     if (!grn_open(ctx, fis, path, O_RDWR|O_CREAT|O_EXCL)) {
-      if ((header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, &fis->fmo, fis, 0, b))) {
+      header = (struct _grn_io_header *)GRN_MMAP(&grn_gctx, NULL,
+                                                 &fis->fmo, fis, 0, b);
+      if (header) {
+        header->version = version;
         header->header_size = header_size;
         header->segment_size = segment_size;
         header->max_segment = max_segment;
@@ -280,7 +311,7 @@ grn_io_create(grn_ctx *ctx, const char *path, uint32_t header_size, uint32_t seg
           }
           GRN_GFREE(io);
         }
-        GRN_MUNMAP(&grn_gctx, &fis->fmo, header, b);
+        GRN_MUNMAP(&grn_gctx, NULL, &fis->fmo, fis, header, b);
       }
       grn_close(ctx, fis);
     }
@@ -463,9 +494,9 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
 {
   grn_io *io;
   struct stat s;
-  fileinfo *fis;
+  fileinfo fi;
   uint32_t flags = 0;
-  uint32_t b, max_nfiles;
+  uint32_t b;
   uint32_t header_size = 0, segment_size = 0, max_segment = 0, bs;
   if (!path || !*path || (strlen(path) > PATH_MAX - 4)) { return NULL; }
   {
@@ -489,13 +520,26 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
   }
   b = grn_io_compute_base(header_size);
   bs = grn_io_compute_base_segment(b, segment_size);
-  max_nfiles = grn_io_compute_max_n_files(segment_size, max_segment,
-                                          bs, GRN_IO_FILE_SIZE);
-  if (!(fis = GRN_GMALLOCN(fileinfo, max_nfiles))) { return NULL; }
-  grn_fileinfo_init(fis, max_nfiles);
-  if (!grn_open(ctx, fis, path, O_RDWR)) {
+  grn_fileinfo_init(&fi, 1);
+  if (!grn_open(ctx, &fi, path, O_RDWR)) {
     struct _grn_io_header *header;
-    if ((header = GRN_MMAP(&grn_gctx, &fis->fmo, fis, 0, b))) {
+    header = GRN_MMAP(&grn_gctx, NULL, &(fi.fmo), &fi, 0, b);
+    if (header) {
+      unsigned long file_size;
+      unsigned int max_nfiles;
+      fileinfo *fis;
+
+      file_size = grn_io_compute_file_size(header->version);
+      max_nfiles = grn_io_compute_max_n_files(segment_size, max_segment,
+                                              bs, file_size);
+      fis = GRN_GMALLOCN(fileinfo, max_nfiles);
+      if (!fis) {
+        GRN_MUNMAP(&grn_gctx, NULL, &(fi.fmo), &fi, header, b);
+        grn_close(ctx, &fi);
+        return NULL;
+      }
+      grn_fileinfo_init(fis, max_nfiles);
+      memcpy(fis, &fi, sizeof(fileinfo));
       if ((io = GRN_GMALLOC(sizeof(grn_io)))) {
         grn_io_mapinfo *maps = NULL;
         if ((maps = GRN_GCALLOC(sizeof(grn_io_mapinfo) * max_segment))) {
@@ -523,48 +567,51 @@ grn_io_open(grn_ctx *ctx, const char *path, grn_io_mode mode)
         }
         GRN_GFREE(io);
       }
-      GRN_MUNMAP(&grn_gctx, &fis->fmo, header, b);
+      GRN_GFREE(fis);
+      GRN_MUNMAP(&grn_gctx, NULL, &(fi.fmo), &fi, header, b);
     }
-    grn_close(ctx, fis);
+    grn_close(ctx, &fi);
   }
-  GRN_GFREE(fis);
   return NULL;
 }
 
 grn_rc
 grn_io_close(grn_ctx *ctx, grn_io *io)
 {
-  int i;
-  fileinfo *fi;
   uint32_t max_nfiles;
 
   max_nfiles = grn_io_max_n_files(io);
   grn_io_unregister(io);
   if (io->ainfo) { GRN_GFREE(io->ainfo); }
   if (io->maps) {
+    int i;
     uint32_t max_segment;
     uint32_t segment_size;
+    unsigned long file_size;
+    uint32_t segments_per_file;
+
     max_segment = grn_io_max_segment(io);
     segment_size = io->header->segment_size;
-    for (mi = io->maps, i = max_segment; i; mi++, i--) {
+    file_size = grn_io_compute_file_size(io->header->version);
+    segments_per_file = file_size / segment_size;
+    for (i = 0; i < max_segment; i++) {
+      grn_io_mapinfo *mi;
+      mi = &(io->maps[i]);
       if (mi->map) {
+        fileinfo *fi = NULL;
         /* if (atomic_read(mi->nref)) { return STILL_IN_USE ; } */
-#ifdef WIN32
-        if ((io->flags & GRN_IO_TEMPORARY)) {
-          GRN_GFREE(mi->map);
-        } else
-#endif /* WIN32 */
-        GRN_MUNMAP(&grn_gctx, &mi->fmo, mi->map, segment_size);
+        if (io->fis) {
+          uint32_t bseg = i + io->base_seg;
+          uint32_t fno = bseg / segments_per_file;
+          fi = &io->fis[fno];
+        }
+        GRN_MUNMAP(&grn_gctx, io, &mi->fmo, fi, mi->map, segment_size);
       }
     }
     GRN_GFREE(io->maps);
   }
-#ifdef WIN32
-  if ((io->flags & GRN_IO_TEMPORARY)) {
-    GRN_GFREE(io->header);
-  } else
-#endif /* WIN32 */
-  GRN_MUNMAP(&grn_gctx, &io->fis->fmo, io->header, io->base);
+  GRN_MUNMAP(&grn_gctx, io, (io->fis ? &io->fis->fmo : NULL),
+             io->fis, io->header, io->base);
   if (io->fis) {
     int i;
     for (i = 0; i < max_nfiles; i++) {
@@ -634,14 +681,13 @@ grn_io_size(grn_ctx *ctx, grn_io *io, uint64_t *size)
   uint64_t tsize = 0;
   char buffer[PATH_MAX];
   uint32_t nfiles;
+
   if (io->header->curr_size) {
-    nfiles = (uint32_t) ((io->header->curr_size + GRN_IO_FILE_SIZE - 1) / GRN_IO_FILE_SIZE);
+    unsigned long file_size;
+    file_size = grn_io_compute_file_size(io->header->version);
+    nfiles = (uint32_t) ((io->header->curr_size + file_size - 1) / file_size);
   } else {
-    uint32_t bs = io->base_seg;
-    uint32_t max_segment = io->header->max_segment;
-    uint32_t segment_size = io->header->segment_size;
-    nfiles = (uint32_t) (((uint64_t)segment_size * (max_segment + bs) + GRN_IO_FILE_SIZE - 1)
-                    / GRN_IO_FILE_SIZE);
+    nfiles = grn_io_max_n_files(io);
   }
   for (fno = 0; fno < nfiles; fno++) {
     gen_pathname(io->path, buffer, fno);
@@ -719,7 +765,8 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos,
 {
   uint32_t rest = 0, size = *value_len + sizeof(grn_io_ja_ehead);
   uint32_t segment_size = io->header->segment_size;
-  uint32_t segments_per_file = GRN_IO_FILE_SIZE / segment_size;
+  unsigned long file_size = grn_io_compute_file_size(io->header->version);
+  uint32_t segments_per_file = file_size / segment_size;
   uint32_t bseg = segment + io->base_seg;
   int fno = bseg / segments_per_file;
   fileinfo *fi = &io->fis[fno];
@@ -731,9 +778,9 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos,
     *value_len = 0;
     return GRN_NO_MEMORY_AVAILABLE;
   }
-  if (pos + size > GRN_IO_FILE_SIZE) {
-    rest = pos + size - GRN_IO_FILE_SIZE;
-    size = GRN_IO_FILE_SIZE - pos;
+  if (pos + size > file_size) {
+    rest = pos + size - file_size;
+    size = file_size - pos;
   }
   if (!grn_opened(fi)) {
     char path[PATH_MAX];
@@ -793,7 +840,7 @@ grn_io_read_ja(grn_io *io, grn_ctx *ctx, grn_io_ja_einfo *einfo, uint32_t epos,
           return ctx->rc;
         }
       }
-      size = rest > GRN_IO_FILE_SIZE ? GRN_IO_FILE_SIZE : rest;
+      size = rest > file_size ? file_size : rest;
       if (grn_pread(ctx, fi, vr, size, 0)) {
         *value = NULL;
         *value_len = 0;
@@ -815,15 +862,16 @@ grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key,
   grn_rc rc;
   uint32_t rest = 0, size = value_len + sizeof(grn_io_ja_ehead);
   uint32_t segment_size = io->header->segment_size;
-  uint32_t segments_per_file = GRN_IO_FILE_SIZE / segment_size;
+  unsigned long file_size = grn_io_compute_file_size(io->header->version);
+  uint32_t segments_per_file = file_size / segment_size;
   uint32_t bseg = segment + io->base_seg;
   int fno = bseg / segments_per_file;
   fileinfo *fi = &io->fis[fno];
   off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg;
   off_t pos = (uint64_t)segment_size * (bseg % segments_per_file) + offset + base;
-  if (pos + size > GRN_IO_FILE_SIZE) {
-    rest = pos + size - GRN_IO_FILE_SIZE;
-    size = GRN_IO_FILE_SIZE - pos;
+  if (pos + size > file_size) {
+    rest = pos + size - file_size;
+    size = file_size - pos;
   }
   if (!grn_opened(fi)) {
     char path[PATH_MAX];
@@ -854,7 +902,7 @@ grn_io_write_ja(grn_io *io, grn_ctx *ctx, uint32_t key,
         gen_pathname(io->path, path, fno);
         if ((rc = grn_open(ctx, fi, path, O_RDWR|O_CREAT))) { return rc; }
       }
-      size = rest > GRN_IO_FILE_SIZE ? GRN_IO_FILE_SIZE : rest;
+      size = rest > file_size ? file_size : rest;
       if ((rc = grn_pwrite(ctx, fi, vr, size, 0))) { return rc; }
       vr += size;
       rest -= size;
@@ -869,7 +917,8 @@ grn_io_write_ja_ehead(grn_io *io, grn_ctx *ctx, uint32_t key,
 {
   grn_rc rc;
   uint32_t segment_size = io->header->segment_size;
-  uint32_t segments_per_file = GRN_IO_FILE_SIZE / segment_size;
+  unsigned long file_size = grn_io_compute_file_size(io->header->version);
+  uint32_t segments_per_file = file_size / segment_size;
   uint32_t bseg = segment + io->base_seg;
   int fno = bseg / segments_per_file;
   fileinfo *fi = &io->fis[fno];
@@ -983,7 +1032,7 @@ grn_io_win_unmap(grn_io_win *iw)
 }
 
 #define DO_MAP(io,fmo,fi,pos,size,segno,res) do {\
-  if (((res) = GRN_MMAP(&grn_gctx, (fmo), (fi), (pos), (size)))) {\
+  if (((res) = GRN_MMAP(&grn_gctx, (io), (fmo), (fi), (pos), (size)))) {\
     uint32_t nmaps;\
     if (io->max_map_seg < segno) { io->max_map_seg = segno; }\
     GRN_ATOMIC_ADD_EX(&io->nmaps, 1, nmaps);\
@@ -999,7 +1048,8 @@ grn_io_win_unmap(grn_io_win *iw)
   if ((io->flags & GRN_IO_TEMPORARY)) {\
     DO_MAP(io, &info->fmo, NULL, 0, segment_size, segno, info->map);\
   } else {\
-    uint32_t segments_per_file = GRN_IO_FILE_SIZE / segment_size;\
+    unsigned long file_size = grn_io_compute_file_size(io->header->version);\
+    uint32_t segments_per_file = file_size / segment_size;\
     uint32_t bseg = segno + io->base_seg;\
     uint32_t fno = bseg / segments_per_file;\
     off_t base = fno ? 0 : io->base - (uint64_t)segment_size * io->base_seg;\
@@ -1053,7 +1103,8 @@ grn_io_seg_expire(grn_ctx *ctx, grn_io *io, uint32_t segno, uint32_t nretry)
         }
       } else {
         uint32_t nmaps;
-        GRN_MUNMAP(&grn_gctx, &info->fmo, info->map, io->header->segment_size);
+        GRN_MUNMAP(&grn_gctx, io, &info->fmo, NULL,
+                   info->map, io->header->segment_size);
         info->map = NULL;
         GRN_ATOMIC_ADD_EX(pnref, -(GRN_IO_MAX_REF + 1), nref);
         GRN_ATOMIC_ADD_EX(&io->nmaps, -1, nmaps);
@@ -1084,7 +1135,8 @@ grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
         }
         for (m = io->max_map_seg; m; info++, m--) {
           if (info->map) {
-            GRN_MUNMAP(&grn_gctx, &info->fmo, info->map, io->header->segment_size);
+            GRN_MUNMAP(&grn_gctx, io, &info->fmo, NULL,
+                       info->map, io->header->segment_size);
             info->map = NULL;
             info->nref = 0;
             info->count = grn_gtick;
@@ -1109,7 +1161,8 @@ grn_io_expire(grn_ctx *ctx, grn_io *io, int count_thresh, uint32_t limit)
           uint32_t nmaps, nref, *pnref = &info->nref;
           GRN_ATOMIC_ADD_EX(pnref, 1, nref);
           if (!nref && info->map && (grn_gtick - info->count) > count_thresh) {
-            GRN_MUNMAP(&grn_gctx, &info->fmo, info->map, io->header->segment_size);
+            GRN_MUNMAP(&grn_gctx, io, &info->fmo, NULL,
+                       info->map, io->header->segment_size);
             GRN_ATOMIC_ADD_EX(&io->nmaps, -1, nmaps);
             info->map = NULL;
             info->count = grn_gtick;
@@ -1167,17 +1220,13 @@ grn_expire(grn_ctx *ctx, int count_thresh, uint32_t limit)
 void *
 grn_io_anon_map(grn_ctx *ctx, grn_io_mapinfo *mi, size_t length)
 {
-  return (mi->map = GRN_MMAP(ctx, &mi->fmo, NULL, 0, length));
+  return (mi->map = GRN_MMAP(ctx, NULL, &mi->fmo, NULL, 0, length));
 }
 
 void
 grn_io_anon_unmap(grn_ctx *ctx, grn_io_mapinfo *mi, size_t length)
 {
-  /* support WIN32 */
-#ifdef WIN32
-  return GRN_FREE(mi->map);
-#endif
-  GRN_MUNMAP(ctx, &mi->fmo, mi->map, length);
+  GRN_MUNMAP(ctx, NULL, &mi->fmo, NULL, mi->map, length);
 }
 
 grn_rc
@@ -1247,53 +1296,15 @@ static size_t mmap_size = 0;
 
 #ifdef WIN32
 
-#ifdef WIN32_FMO_EACH
-
 inline static grn_rc
-grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+grn_open_v1(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
 {
-  if ((flags & O_CREAT)) {
-    DWORD dwCreationDisposition;
-    if (flags & O_EXCL) {
-      dwCreationDisposition = CREATE_NEW;
-    } else {
-      dwCreationDisposition = OPEN_ALWAYS;
-    }
-    fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                        dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
-    if (fi->fh == INVALID_HANDLE_VALUE) {
-      SERR("CreateFile");
-      return ctx->rc;
-    }
-    goto exit;
-  }
-  if ((flags & O_TRUNC)) {
-    CloseHandle(fi->fh);
-    fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                        TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
-    if (fi->fh == INVALID_HANDLE_VALUE) {
-      SERR("CreateFile");
-      return ctx->rc;
-    }
-    goto exit;
-  }
-  /* O_RDWR only */
-  fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
-                      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
-  if (fi->fh == INVALID_HANDLE_VALUE) {
-    SERR("CreateFile");
-    return ctx->rc;
-  }
-exit:
   CRITICAL_SECTION_INIT(fi->cs);
   return GRN_SUCCESS;
 }
 
 inline static void *
-grn_mmap(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length)
+grn_mmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length)
 {
   void *res;
   if (!fi) {
@@ -1320,13 +1331,21 @@ grn_mmap(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi, off_t offset, size_t length)
 }
 
 inline static int
-grn_munmap(grn_ctx *ctx, HANDLE *fmo, void *start, size_t length)
+grn_munmap_v1(grn_ctx *ctx, HANDLE *fmo, fileinfo *fi,
+              void *start, size_t length)
 {
   int r = 0;
+
+  if (!fi) {
+    GRN_GFREE(start);
+    return r;
+  }
+
   if (!fmo) {
     GRN_GFREE(start);
     return r;
   }
+
   if (*fmo) {
     if (UnmapViewOfFile(start)) {
       mmap_size -= length;
@@ -1347,65 +1366,13 @@ grn_munmap(grn_ctx *ctx, HANDLE *fmo, void *start, size_t length)
   } else {
     GRN_GFREE(start);
   }
-  return r;
-}
 
-inline static grn_rc
-grn_close(grn_ctx *ctx, fileinfo *fi)
-{
-  if (fi->fmo != NULL) {
-    GRN_LOG(ctx, GRN_LOG_ALERT, "file mapping object exists");
-  }
-  if (fi->fh != INVALID_HANDLE_VALUE) {
-    CloseHandle(fi->fh);
-    CRITICAL_SECTION_FIN(fi->cs);
-    fi->fh = INVALID_HANDLE_VALUE;
-  }
-  return GRN_SUCCESS;
+  return r;
 }
 
-#else /* WIN32_FMO_EACH */
 inline static grn_rc
-grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+grn_open_v0(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
 {
-  /* may be wrong if flags is just only O_RDWR */
-  if ((flags & O_CREAT)) {
-    DWORD dwCreationDisposition;
-    if (flags & O_EXCL) {
-      dwCreationDisposition = CREATE_NEW;
-    } else {
-      dwCreationDisposition = OPEN_ALWAYS;
-    }
-    fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                        dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
-    if (fi->fh == INVALID_HANDLE_VALUE) {
-      SERR("CreateFile");
-      return ctx->rc;
-    }
-    goto exit;
-  }
-  if ((flags & O_TRUNC)) {
-    CloseHandle(fi->fh);
-    /* unable to assign OPEN_ALWAYS and TRUNCATE_EXISTING at once */
-    fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                        TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
-    if (fi->fh == INVALID_HANDLE_VALUE) {
-      SERR("CreateFile");
-      return ctx->rc;
-    }
-    goto exit;
-  }
-  /* O_RDWR only */
-  fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
-                      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
-  if (fi->fh == INVALID_HANDLE_VALUE) {
-    SERR("CreateFile");
-    return ctx->rc;
-  }
-exit:
   /* signature may be wrong.. */
   fi->fmo = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, NULL);
   /* open failed */
@@ -1416,7 +1383,7 @@ exit:
     /* failed again */
     if (fi->fmo == NULL) {
       /* try to create fmo */
-      fi->fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0, GRN_IO_FILE_SIZE, NULL);
+      fi->fmo = CreateFileMapping(fi->fh, NULL, PAGE_READWRITE, 0, GRN_IO_FILE_SIZE_V0, NULL);
     }
     // funlock
   }
@@ -1438,11 +1405,11 @@ exit:
 }
 
 inline static void *
-grn_mmap(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
+grn_mmap_v0(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
 {
   void *res;
   if (!fi) { return GRN_GCALLOC(length); }
-  /* file must be exceeded to GRN_IO_FILE_SIZE when FileMappingObject created.
+  /* file must be exceeded to GRN_IO_FILE_SIZE_V0 when FileMappingObject created.
      and, after fmo created, it's not allowed to expand the size of file.
   DWORD tail = (DWORD)(offset + length);
   DWORD filesize = GetFileSize(fi->fh, NULL);
@@ -1469,8 +1436,13 @@ grn_mmap(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
 }
 
 inline static int
-grn_munmap(grn_ctx *ctx, void *start, size_t length)
+grn_munmap_v0(grn_ctx *ctx, fileinfo *fi, void *start, size_t length)
 {
+  if (!fi) {
+    GRN_GFREE(start);
+    return 0;
+  }
+
   if (UnmapViewOfFile(start)) {
     mmap_size -= length;
     return 0;
@@ -1484,6 +1456,127 @@ grn_munmap(grn_ctx *ctx, void *start, size_t length)
 }
 
 inline static grn_rc
+grn_open_common(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+{
+  /* may be wrong if flags is just only O_RDWR */
+  if ((flags & O_CREAT)) {
+    DWORD dwCreationDisposition;
+    if (flags & O_EXCL) {
+      dwCreationDisposition = CREATE_NEW;
+    } else {
+      dwCreationDisposition = OPEN_ALWAYS;
+    }
+    fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                        dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
+    if (fi->fh == INVALID_HANDLE_VALUE) {
+      SERR("CreateFile");
+      goto exit;
+    }
+    goto exit;
+  }
+  if ((flags & O_TRUNC)) {
+    CloseHandle(fi->fh);
+    /* unable to assign OPEN_ALWAYS and TRUNCATE_EXISTING at once */
+    fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                        TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+    if (fi->fh == INVALID_HANDLE_VALUE) {
+      SERR("CreateFile");
+      goto exit;
+    }
+    goto exit;
+  }
+  /* O_RDWR only */
+  fi->fh = CreateFile(path, GRN_IO_FILE_CREATE_MODE,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+  if (fi->fh == INVALID_HANDLE_VALUE) {
+    SERR("CreateFile");
+    goto exit;
+  }
+
+exit :
+  return ctx->rc;
+}
+
+inline static grn_rc
+grn_open(grn_ctx *ctx, fileinfo *fi, const char *path, int flags)
+{
+  grn_rc rc;
+  struct _grn_io_header io_header;
+  DWORD header_size;
+  DWORD read_bytes;
+  int version = grn_io_version_default;
+
+  rc = grn_open_common(ctx, fi, path, flags);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+
+  header_size = sizeof(struct _grn_io_header);
+  ReadFile(fi->fh, &io_header, header_size, &read_bytes, NULL);
+  if (read_bytes == header_size) {
+    version = io_header.version;
+  }
+  SetFilePointer(fi->fh, 0, NULL, FILE_BEGIN);
+
+  if (version == 0) {
+    return grn_open_v0(ctx, fi, path, flags);
+  } else {
+    return grn_open_v1(ctx, fi, path, flags);
+  }
+}
+
+inline static int
+grn_guess_io_version(grn_ctx *ctx, grn_io *io, fileinfo *fi)
+{
+  if (io) {
+    return io->header->version;
+  }
+
+  if (fi) {
+    if (fi->fmo) {
+      return 0;
+    } else {
+      return 1;
+    }
+  }
+
+  return grn_io_version_default;
+}
+
+inline static void *
+grn_mmap(grn_ctx *ctx, grn_io *io, HANDLE *fmo,
+         fileinfo *fi, off_t offset, size_t length)
+{
+  int version;
+
+  version = grn_guess_io_version(ctx, io, fi);
+
+  if (version == 0) {
+    return grn_mmap_v0(ctx, fi, offset, length);
+  } else {
+    return grn_mmap_v1(ctx, fmo, fi, offset, length);
+  }
+}
+
+inline static int
+grn_munmap(grn_ctx *ctx, grn_io *io,
+           HANDLE *fmo, fileinfo *fi, void *start, size_t length)
+{
+  int version;
+
+  version = grn_guess_io_version(ctx, io, fi);
+
+  if (version == 0) {
+    return grn_munmap_v0(ctx, fi, start, length);
+  } else {
+    return grn_munmap_v1(ctx, fmo, fi, start, length);
+  }
+}
+
+inline static grn_rc
 grn_close(grn_ctx *ctx, fileinfo *fi)
 {
   if (fi->fmo != NULL) {
@@ -1497,7 +1590,6 @@ grn_close(grn_ctx *ctx, fileinfo *fi)
   }
   return GRN_SUCCESS;
 }
-#endif /* WIN32_FMO_EACH */
 
 inline static void
 grn_fileinfo_init(fileinfo *fis, int nfis)
@@ -1616,7 +1708,7 @@ grn_close(grn_ctx *ctx, fileinfo *fi)
 #include <sys/mman.h>
 
 inline static void *
-grn_mmap(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
+grn_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, off_t offset, size_t length)
 {
   void *res;
   int fd, flags;
@@ -1646,7 +1738,8 @@ grn_mmap(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length)
 
 #ifdef USE_FAIL_MALLOC
 inline static void *
-grn_fail_mmap(grn_ctx *ctx, fileinfo *fi, off_t offset, size_t length,
+grn_fail_mmap(grn_ctx *ctx, grn_io *io, fileinfo *fi,
+              off_t offset, size_t length,
               const char* file, int line, const char *func)
 {
   if (grn_fail_malloc_check(length, file, line, func)) {
@@ -1669,7 +1762,7 @@ grn_msync(grn_ctx *ctx, void *start, size_t length)
 }
 
 inline static int
-grn_munmap(grn_ctx *ctx, void *start, size_t length)
+grn_munmap(grn_ctx *ctx, grn_io *io, fileinfo *fi, void *start, size_t length)
 {
   int res;
   res = munmap(start, length);
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index