CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
LocalCacheFile.cc
Go to the documentation of this file.
3 #include <utility>
4 #include <iostream>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9 #include <errno.h>
10 
11 static const IOOffset CHUNK_SIZE = 128*1024*1024;
12 
13 static void
14 nowrite(const char *why)
15 {
16  throw cms::Exception("LocalCacheFile")
17  << "Cannot change file but operation '" << why << "' was called";
18 }
19 
20 
21 LocalCacheFile::LocalCacheFile(Storage *base, const std::string &tmpdir /* = "" */)
22  : image_(base->size()),
23  file_(0),
24  storage_(base),
25  closedFile_(false),
26  cacheCount_(0),
27  cacheTotal_((image_ + CHUNK_SIZE - 1) / CHUNK_SIZE)
28 {
29  present_.resize(cacheTotal_, 0);
30 
31  std::string pattern(tmpdir);
32  if (pattern.empty())
33  if (char *p = getenv("TMPDIR"))
34  pattern = p;
35  if (pattern.empty())
36  pattern = "/tmp";
37  pattern += "/cmssw-shadow-XXXXXX";
38 
39  std::vector<char> temp(pattern.c_str(), pattern.c_str()+pattern.size()+1);
40  int fd = mkstemp(&temp[0]);
41  if (fd == -1)
42  throw cms::Exception("LocalCacheFile")
43  << "Cannot create temporary file '" << pattern << "': "
44  << strerror(errno) << " (error " << errno << ")";
45 
46  unlink(&temp[0]);
47  file_ = new File(fd);
49 }
50 
52 {
53  delete file_;
54  delete storage_;
55 }
56 
57 void
59 {
60  start = (start / CHUNK_SIZE) * CHUNK_SIZE;
61  end = std::min(end, image_);
62 
63  IOSize nread = 0;
64  IOSize index = start / CHUNK_SIZE;
65 
66  while (start < end)
67  {
68  IOSize len = std::min(image_ - start, CHUNK_SIZE);
69  if (! present_[index])
70  {
71  void *window = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, file_->fd(), start);
72  if (window == MAP_FAILED)
73  throw cms::Exception("LocalCacheFile")
74  << "Unable to map a window of local cache file: "
75  << strerror(errno) << " (error " << errno << ")";
76 
77  try
78  {
79  nread = storage_->read(window, len, start);
80  }
81  catch (cms::Exception &e)
82  {
83  munmap(window, len);
84  throw cms::Exception("LocalCacheFile")
85  << "Unable to cache " << len << " byte file segment at " << start
86  << ": " << e.what();
87  }
88 
89  munmap(window, len);
90 
91  if (nread != len)
92  throw cms::Exception("LocalCacheFile")
93  << "Unable to cache " << len << " byte file segment at " << start
94  << ": got only " << nread << " bytes back";
95 
96  present_[index] = 1;
97  ++cacheCount_;
98  if (cacheCount_ == cacheTotal_)
99  {
100  storage_->close();
101  closedFile_ = true;
102  }
103  }
104 
105  start += len;
106  ++index;
107  }
108 }
109 
110 IOSize
112 {
113  IOOffset here = file_->position();
114  cache(here, here + n);
115 
116  return file_->read(into, n);
117 }
118 
119 IOSize
121 {
122  cache(pos, pos + n);
123  return file_->read(into, n, pos);
124 }
125 
126 IOSize
128 {
129  IOOffset start = file_->position();
130  IOOffset end = start;
131  for (IOSize i = 0; i < n; ++i)
132  end += into[i].size();
133  cache(start, end);
134 
135  return file_->readv(into, n);
136 }
137 
138 IOSize
140 {
141  for (IOSize i = 0; i < n; ++i)
142  {
143  IOOffset start = into[i].offset();
144  IOOffset end = start + into[i].size();
145  cache(start, end);
146  }
147 
148  return storage_->readv(into, n);
149 }
150 
151 IOSize
153 { nowrite("write"); return 0; }
154 
155 IOSize
157 { nowrite("write"); return 0; }
158 
159 IOSize
161 { nowrite("writev"); return 0; }
162 
163 IOSize
165 { nowrite("writev"); return 0; }
166 
167 IOOffset
169 { return file_->position(offset, whence); }
170 
171 void
173 { nowrite("resize"); }
174 
175 void
177 { nowrite("flush"); }
178 
179 void
181 {
182  if (!closedFile_)
183  {
184  storage_->close();
185  }
186  file_->close();
187 }
188 
189 bool
191 {
192  for (IOSize i = 0; i < n; ++i)
193  {
194  IOOffset start = what[i].offset();
195  IOOffset end = start + what[i].size();
196  cache(start, end);
197  }
198 
199  return file_->prefetch(what, n);
200 }
virtual char const * what() const
Definition: Exception.cc:97
tuple base
Main Program
Definition: newFWLiteAna.py:92
virtual IOSize readv(IOBuffer *into, IOSize length)
Definition: File.cc:236
int i
Definition: DBlmapReader.cc:9
def window
Definition: svgfig.py:642
void cache(IOOffset start, IOOffset end)
virtual IOSize readv(IOPosBuffer *into, IOSize buffers)
Definition: Storage.cc:31
virtual IOSize read(void *into, IOSize n, IOOffset pos)
Definition: Storage.cc:17
unsigned int cacheTotal_
virtual void flush(void)
Definition: Storage.h:8
#define min(a, b)
Definition: mlp_lapack.h:161
virtual void close(void)
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
Definition: File.cc:210
virtual IOSize read(void *into, IOSize n)
Definition: File.cc:231
Relative
Definition: Storage.h:11
unsigned int cacheCount_
virtual void close(void)
Definition: Storage.cc:128
virtual IOOffset position(void) const
Definition: Storage.cc:95
#define end
Definition: vmac.h:38
virtual IOSize writev(const IOBuffer *from, IOSize n)
LocalCacheFile(Storage *base, const std::string &tmpdir="")
static const IOOffset CHUNK_SIZE
int read(void)
Definition: IOInput.cc:54
unsigned int offset(bool)
std::vector< char > present_
IOOffset offset(void) const
Definition: IOPosBuffer.h:50
static std::string from(" from ")
virtual IOOffset position(IOOffset offset, Relative whence=SET)
Definition: UnixFile.cc:112
IOSize size(void) const
Definition: IOPosBuffer.h:60
virtual IOSize write(const void *from, IOSize n)
virtual IOOffset size(void) const
Definition: Storage.cc:102
virtual IOSize readv(IOBuffer *into, IOSize n)
int64_t IOOffset
Definition: IOTypes.h:19
virtual void resize(IOOffset size)
Definition: UnixFile.cc:129
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
virtual void resize(IOOffset size)
size_t IOSize
Definition: IOTypes.h:14
virtual IOFD fd(void) const
Definition: IOChannel.cc:73
virtual void close(void)
Definition: File.cc:277
Storage * storage_
tuple size
Write out results.
static void nowrite(const char *why)