SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MemoryMappedFile.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2009 Soeren Sonnenburg
8  * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  */
10 
11 #ifndef __MEMORYMAPPEDFILE_H__
12 #define __MEMORYMAPPEDFILE_H__
13 
14 #include <shogun/io/SGIO.h>
15 #include <shogun/base/SGObject.h>
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 
25 namespace shogun
26 {
31 template <class T> class CMemoryMappedFile : public CSGObject
32 {
33  public:
36  {
37  SG_UNSTABLE("CMemoryMappedFile::CMemoryMappedFile()",
38  "\n");
39 
40  fd = 0;
41  length = 0;
42  address = NULL;
43  rw = 'r';
45 
46  set_generic<T>();
47  }
48 
62  CMemoryMappedFile(const char* fname, char flag='r', int64_t fsize=0)
63  : CSGObject()
64  {
65  REQUIRE(flag=='w' || flag=='r', "Only 'r' and 'w' flags are allowed")
66 
68  rw=flag;
69 
70  int open_flags=O_RDONLY;
71  int mmap_prot=PROT_READ;
72  int mmap_flags=MAP_PRIVATE;
73 
74  if (rw=='w')
75  {
76  open_flags=O_RDWR | O_CREAT;
77  mmap_prot=PROT_READ|PROT_WRITE;
78  mmap_flags=MAP_SHARED;
79  }
80 
81  fd = open(fname, open_flags, S_IRWXU | S_IRWXG | S_IRWXO);
82  if (fd == -1)
83  SG_ERROR("Error opening file\n")
84 
85  if (rw=='w' && fsize)
86  {
87  uint8_t byte=0;
88  if (lseek(fd, fsize, SEEK_SET) != fsize || write(fd, &byte, 1) != 1)
89  SG_ERROR("Error creating file of size %ld bytes\n", fsize)
90  }
91 
92  struct stat sb;
93  if (fstat(fd, &sb) == -1)
94  SG_ERROR("Error determining file size\n")
95 
96  length = sb.st_size;
97  address = mmap(NULL, length, mmap_prot, mmap_flags, fd, 0);
98  if (address == MAP_FAILED)
99  SG_ERROR("Error mapping file")
100 
101  set_generic<T>();
102  }
103 
106  {
107  munmap(address, length);
108  if (rw=='w' && last_written_byte && ftruncate(fd, last_written_byte) == -1)
109 
110  {
111  close(fd);
112  SG_ERROR("Error Truncating file to %ld bytes\n", last_written_byte)
113  }
114  close(fd);
115  }
116 
126  inline T* get_map()
127  {
128  return (T*) address;
129  }
130 
135  uint64_t get_length()
136  {
137  return length/sizeof(T);
138  }
139 
144  uint64_t get_size()
145  {
146  return length;
147  }
148 
160  char* get_line(uint64_t& len, uint64_t& offs)
161  {
162  char* s = (char*) address;
163  for (uint64_t i=offs; i<length; i++)
164  {
165  if (s[i] == '\n')
166  {
167  char* line=&s[offs];
168  len=i-offs;
169  offs=i+1;
170  return line;
171  }
172  }
173 
174  len=0;
175  offs=length;
176  return NULL;
177  }
178 
189  void write_line(const char* line, uint64_t len, uint64_t& offs)
190  {
191  char* s = ((char*) address) + offs;
192  if (len+1+offs > length)
193  SG_ERROR("Writing beyond size of file\n")
194 
195  for (uint64_t i=0; i<len; i++)
196  s[i] = line[i];
197 
198  s[len]='\n';
199  offs+=length+1;
200  last_written_byte=offs-1;
201  }
202 
214  inline void set_truncate_size(uint64_t sz=0)
215  {
217  }
218 
223  int32_t get_num_lines()
224  {
225  char* s = (char*) address;
226  int32_t linecount=0;
227  for (uint64_t i=0; i<length; i++)
228  {
229  if (s[i] == '\n')
230  linecount++;
231  }
232 
233  return linecount;
234  }
235 
243  inline T operator[](uint64_t index) const
244  {
245  return ((T*)address)[index];
246  }
247 
255  inline T operator[](int32_t index) const
256  {
257  return ((T*)address)[index];
258  }
259 
261  virtual const char* get_name() const { return "MemoryMappedFile"; }
262 
263  protected:
265  int fd;
267  uint64_t length;
269  void* address;
271  char rw;
272 
275 };
276 }
277 #endif

SHOGUN Machine Learning Toolbox - Documentation