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 
24 LocalCacheFile::LocalCacheFile(std::unique_ptr<Storage> base, const std::string &tmpdir /* = "" */)
25  : image_(base->size()),
26  file_(),
27  storage_(std::move(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_ = std::make_unique<File>(fd);
54  file_->resize(image_);
55 }
56 
58 {
59 }
60 
61 void
63 {
64  start = (start / CHUNK_SIZE) * CHUNK_SIZE;
65  end = std::min(end, image_);
66 
67  IOSize nread = 0;
68  IOSize index = start / CHUNK_SIZE;
69 
70  while (start < end)
71  {
72  IOSize len = std::min(image_ - start, CHUNK_SIZE);
73  if (! present_[index])
74  {
75  void *window = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, file_->fd(), start);
76  if (window == MAP_FAILED)
77  {
79  ex << "Unable to map a window of local cache file: "
80  << strerror(errno) << " (error " << errno << ")";
81  ex.addContext("LocalCacheFile::cache()");
82  throw ex;
83  }
84 
85  try
86  {
87  nread = storage_->read(window, len, start);
88  }
89  catch (cms::Exception &e)
90  {
91  munmap(window, len);
92  std::ostringstream ost;
93  ost << "Unable to cache " << len << " byte file segment at " << start << ": ";
95  ex.addContext("LocalCacheFile::cache()");
96  throw ex;
97  }
98 
99  munmap(window, len);
100 
101  if (nread != len)
102  {
104  ex << "Unable to cache " << len << " byte file segment at " << start
105  << ": got only " << nread << " bytes back";
106  ex.addContext("LocalCacheFile::cache()");
107  throw ex;
108  }
109 
110  present_[index] = 1;
111  ++cacheCount_;
112  if (cacheCount_ == cacheTotal_)
113  {
114  storage_->close();
115  closedFile_ = true;
116  }
117  }
118 
119  start += len;
120  ++index;
121  }
122 }
123 
124 IOSize
126 {
127  IOOffset here = file_->position();
128  cache(here, here + n);
129 
130  return file_->read(into, n);
131 }
132 
133 IOSize
135 {
136  cache(pos, pos + n);
137  return file_->read(into, n, pos);
138 }
139 
140 IOSize
142 {
143  IOOffset start = file_->position();
144  IOOffset end = start;
145  for (IOSize i = 0; i < n; ++i)
146  end += into[i].size();
147  cache(start, end);
148 
149  return file_->readv(into, n);
150 }
151 
152 IOSize
154 {
155  for (IOSize i = 0; i < n; ++i)
156  {
157  IOOffset start = into[i].offset();
158  IOOffset end = start + into[i].size();
159  cache(start, end);
160  }
161 
162  return storage_->readv(into, n);
163 }
164 
165 IOSize
166 LocalCacheFile::write(const void */*from*/, IOSize)
167 { nowrite("write"); return 0; }
168 
169 IOSize
170 LocalCacheFile::write(const void */*from*/, IOSize, IOOffset /*pos*/)
171 { nowrite("write"); return 0; }
172 
173 IOSize
175 { nowrite("writev"); return 0; }
176 
177 IOSize
179 { nowrite("writev"); return 0; }
180 
181 IOOffset
183 { return file_->position(offset, whence); }
184 
185 void
187 { nowrite("resize"); }
188 
189 void
191 { nowrite("flush"); }
192 
193 void
195 {
196  if (!closedFile_)
197  {
198  storage_->close();
199  }
200  file_->close();
201 }
202 
203 bool
205 {
206  for (IOSize i = 0; i < n; ++i)
207  {
208  IOOffset start = what[i].offset();
209  IOOffset end = start + what[i].size();
210  cache(start, end);
211  }
212 
213  return file_->prefetch(what, n);
214 }
tuple base
Main Program
Definition: newFWLiteAna.py:91
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)
unsigned int cacheTotal_
virtual void flush(void)
virtual void close(void)
edm::propagate_const< std::unique_ptr< Storage > > storage_
Relative
Definition: Storage.h:23
unsigned int cacheCount_
virtual IOOffset position(void) const
Definition: Storage.cc:95
def move
Definition: eostools.py:510
tuple fd
Definition: ztee.py:136
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
virtual IOSize writev(const IOBuffer *from, IOSize n)
static const IOOffset CHUNK_SIZE
int read(void)
Definition: IOInput.cc:54
std::vector< char > present_
IOOffset offset(void) const
Definition: IOPosBuffer.h:54
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
LocalCacheFile(std::unique_ptr< Storage > base, const std::string &tmpdir="")
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 bool prefetch(const IOPosBuffer *what, IOSize n)
edm::propagate_const< std::unique_ptr< File > > file_
virtual void resize(IOOffset size)
size_t IOSize
Definition: IOTypes.h:14
volatile std::atomic< bool > shutdown_flag false
tuple size
Write out results.
static void nowrite(const std::string &why)