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 #include <sstream>
11 
12 static const IOOffset CHUNK_SIZE = 128*1024*1024;
13 
14 static void
15 nowrite(const std::string &why)
16 {
17  cms::Exception ex("LocalCacheFile");
18  ex << "Cannot change file but operation '" << why << "' was called";
19  ex.addContext("LocalCacheFile::" + why + "()");
20  throw ex;
21 }
22 
23 
25  : image_(base->size()),
26  file_(0),
27  storage_(base),
28  closedFile_(false),
29  cacheCount_(0),
30  cacheTotal_((image_ + CHUNK_SIZE - 1) / CHUNK_SIZE)
31 {
32  present_.resize(cacheTotal_, 0);
33 
34  std::string pattern(tmpdir);
35  if (pattern.empty())
36  if (char *p = getenv("TMPDIR"))
37  pattern = p;
38  if (pattern.empty())
39  pattern = "/tmp";
40  pattern += "/cmssw-shadow-XXXXXX";
41 
42  std::vector<char> temp(pattern.c_str(), pattern.c_str()+pattern.size()+1);
43  int fd = mkstemp(&temp[0]);
44  if (fd == -1)
45  {
47  ex << "Cannot create temporary file '" << pattern << "': "
48  << strerror(errno) << " (error " << errno << ")";
49  ex.addContext("LocalCacheFile::LocalCacheFile");
50  }
51 
52  unlink(&temp[0]);
53  file_ = new File(fd);
55 }
56 
58 {
59  delete file_;
60  delete storage_;
61 }
62 
63 void
65 {
66  start = (start / CHUNK_SIZE) * CHUNK_SIZE;
67  end = std::min(end, image_);
68 
69  IOSize nread = 0;
70  IOSize index = start / CHUNK_SIZE;
71 
72  while (start < end)
73  {
74  IOSize len = std::min(image_ - start, CHUNK_SIZE);
75  if (! present_[index])
76  {
77  void *window = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, file_->fd(), start);
78  if (window == MAP_FAILED)
79  {
81  ex << "Unable to map a window of local cache file: "
82  << strerror(errno) << " (error " << errno << ")";
83  ex.addContext("LocalCacheFile::cache()");
84  throw ex;
85  }
86 
87  try
88  {
89  nread = storage_->read(window, len, start);
90  }
91  catch (cms::Exception &e)
92  {
93  munmap(window, len);
94  std::ostringstream ost;
95  ost << "Unable to cache " << len << " byte file segment at " << start << ": ";
97  ex.addContext("LocalCacheFile::cache()");
98  throw ex;
99  }
100 
101  munmap(window, len);
102 
103  if (nread != len)
104  {
106  ex << "Unable to cache " << len << " byte file segment at " << start
107  << ": got only " << nread << " bytes back";
108  ex.addContext("LocalCacheFile::cache()");
109  throw ex;
110  }
111 
112  present_[index] = 1;
113  ++cacheCount_;
114  if (cacheCount_ == cacheTotal_)
115  {
116  storage_->close();
117  closedFile_ = true;
118  }
119  }
120 
121  start += len;
122  ++index;
123  }
124 }
125 
126 IOSize
128 {
129  IOOffset here = file_->position();
130  cache(here, here + n);
131 
132  return file_->read(into, n);
133 }
134 
135 IOSize
137 {
138  cache(pos, pos + n);
139  return file_->read(into, n, pos);
140 }
141 
142 IOSize
144 {
146  IOOffset end = start;
147  for (IOSize i = 0; i < n; ++i)
148  end += into[i].size();
149  cache(start, end);
150 
151  return file_->readv(into, n);
152 }
153 
154 IOSize
156 {
157  for (IOSize i = 0; i < n; ++i)
158  {
159  IOOffset start = into[i].offset();
160  IOOffset end = start + into[i].size();
161  cache(start, end);
162  }
163 
164  return storage_->readv(into, n);
165 }
166 
167 IOSize
168 LocalCacheFile::write(const void */*from*/, IOSize)
169 { nowrite("write"); return 0; }
170 
171 IOSize
172 LocalCacheFile::write(const void */*from*/, IOSize, IOOffset /*pos*/)
173 { nowrite("write"); return 0; }
174 
175 IOSize
177 { nowrite("writev"); return 0; }
178 
179 IOSize
181 { nowrite("writev"); return 0; }
182 
183 IOOffset
185 { return file_->position(offset, whence); }
186 
187 void
189 { nowrite("resize"); }
190 
191 void
193 { nowrite("flush"); }
194 
195 void
197 {
198  if (!closedFile_)
199  {
200  storage_->close();
201  }
202  file_->close();
203 }
204 
205 bool
207 {
208  for (IOSize i = 0; i < n; ++i)
209  {
210  IOOffset start = what[i].offset();
211  IOOffset end = start + what[i].size();
212  cache(start, end);
213  }
214 
215  return file_->prefetch(what, n);
216 }
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
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
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)
list pattern
Definition: chain.py:104
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:23
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:37
T min(T a, T b)
Definition: MathUtil.h:58
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:54
virtual IOOffset position(IOOffset offset, Relative whence=SET)
Definition: UnixFile.cc:113
IOSize size(void) const
Definition: IOPosBuffer.h:64
virtual IOSize write(const void *from, IOSize n)
virtual IOOffset size(void) const
Definition: Storage.cc:102
void addContext(std::string const &context)
Definition: Exception.cc:227
virtual IOSize readv(IOBuffer *into, IOSize n)
int64_t IOOffset
Definition: IOTypes.h:19
virtual void resize(IOOffset size)
Definition: UnixFile.cc:130
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
virtual void resize(IOOffset size)
size_t IOSize
Definition: IOTypes.h:14
volatile std::atomic< bool > shutdown_flag false
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 std::string &why)