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 char *why)
16 {
17  throw cms::Exception("LocalCacheFile")
18  << "Cannot change file but operation '" << why << "' was called";
19 }
20 
21 
23  : image_(base->size()),
24  file_(0),
25  storage_(base),
26  closedFile_(false),
27  cacheCount_(0),
28  cacheTotal_((image_ + CHUNK_SIZE - 1) / CHUNK_SIZE)
29 {
30  present_.resize(cacheTotal_, 0);
31 
32  std::string pattern(tmpdir);
33  if (pattern.empty())
34  if (char *p = getenv("TMPDIR"))
35  pattern = p;
36  if (pattern.empty())
37  pattern = "/tmp";
38  pattern += "/cmssw-shadow-XXXXXX";
39 
40  std::vector<char> temp(pattern.c_str(), pattern.c_str()+pattern.size()+1);
41  int fd = mkstemp(&temp[0]);
42  if (fd == -1)
43  throw cms::Exception("LocalCacheFile")
44  << "Cannot create temporary file '" << pattern << "': "
45  << strerror(errno) << " (error " << errno << ")";
46 
47  unlink(&temp[0]);
48  file_ = new File(fd);
50 }
51 
53 {
54  delete file_;
55  delete storage_;
56 }
57 
58 void
60 {
61  start = (start / CHUNK_SIZE) * CHUNK_SIZE;
62  end = std::min(end, image_);
63 
64  IOSize nread = 0;
65  IOSize index = start / CHUNK_SIZE;
66 
67  while (start < end)
68  {
69  IOSize len = std::min(image_ - start, CHUNK_SIZE);
70  if (! present_[index])
71  {
72  void *window = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, file_->fd(), start);
73  if (window == MAP_FAILED)
74  throw cms::Exception("LocalCacheFile")
75  << "Unable to map a window of local cache file: "
76  << strerror(errno) << " (error " << errno << ")";
77 
78  try
79  {
80  nread = storage_->read(window, len, start);
81  }
82  catch (cms::Exception &e)
83  {
84  munmap(window, len);
85  std::ostringstream ost;
86  ost << "Unable to cache " << len << " byte file segment at " << start << ": ";
87  throw cms::Exception("LocalCacheFile", ost.str(), e);
88  }
89 
90  munmap(window, len);
91 
92  if (nread != len)
93  throw cms::Exception("LocalCacheFile")
94  << "Unable to cache " << len << " byte file segment at " << start
95  << ": got only " << nread << " bytes back";
96 
97  present_[index] = 1;
98  ++cacheCount_;
99  if (cacheCount_ == cacheTotal_)
100  {
101  storage_->close();
102  closedFile_ = true;
103  }
104  }
105 
106  start += len;
107  ++index;
108  }
109 }
110 
111 IOSize
113 {
114  IOOffset here = file_->position();
115  cache(here, here + n);
116 
117  return file_->read(into, n);
118 }
119 
120 IOSize
122 {
123  cache(pos, pos + n);
124  return file_->read(into, n, pos);
125 }
126 
127 IOSize
129 {
131  IOOffset end = start;
132  for (IOSize i = 0; i < n; ++i)
133  end += into[i].size();
134  cache(start, end);
135 
136  return file_->readv(into, n);
137 }
138 
139 IOSize
141 {
142  for (IOSize i = 0; i < n; ++i)
143  {
144  IOOffset start = into[i].offset();
145  IOOffset end = start + into[i].size();
146  cache(start, end);
147  }
148 
149  return storage_->readv(into, n);
150 }
151 
152 IOSize
153 LocalCacheFile::write(const void */*from*/, IOSize)
154 { nowrite("write"); return 0; }
155 
156 IOSize
157 LocalCacheFile::write(const void */*from*/, IOSize, IOOffset /*pos*/)
158 { nowrite("write"); return 0; }
159 
160 IOSize
162 { nowrite("writev"); return 0; }
163 
164 IOSize
166 { nowrite("writev"); return 0; }
167 
168 IOOffset
170 { return file_->position(offset, whence); }
171 
172 void
174 { nowrite("resize"); }
175 
176 void
178 { nowrite("flush"); }
179 
180 void
182 {
183  if (!closedFile_)
184  {
185  storage_->close();
186  }
187  file_->close();
188 }
189 
190 bool
192 {
193  for (IOSize i = 0; i < n; ++i)
194  {
195  IOOffset start = what[i].offset();
196  IOOffset end = start + what[i].size();
197  cache(start, end);
198  }
199 
200  return file_->prefetch(what, n);
201 }
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)
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
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
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 char *why)