-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 46071 b: "refs/heads/CMSSW_7_1_X" c: 341ba6c h: "refs/heads/CMSSW_7_1_X" i: 46069: d2a5ab2 46067: 6631cde 46063: 8cba6c7 v: v3
- Loading branch information
Lassi Tuura
committed
Jun 18, 2008
1 parent
c98051f
commit 880f8ae
Showing
3 changed files
with
227 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
--- | ||
refs/heads/gh-pages: ac155dadd83efa75cad55c0508a57a2b9dd3d66c | ||
"refs/heads/CMSSW_7_1_X": 4797eccd42d4cf15638cf44dddb37faf1e97f1c4 | ||
"refs/heads/CMSSW_7_1_X": 341ba6c01d00fb5eb89bc9658a0c17d301dbeefd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#ifndef STORAGE_FACTORY_LOCAL_CACHE_FILE_H | ||
# define STORAGE_FACTORY_LOCAL_CACHE_FILE_H | ||
|
||
# include "Utilities/StorageFactory/interface/Storage.h" | ||
# include "Utilities/StorageFactory/interface/File.h" | ||
# include <vector> | ||
# include <string> | ||
|
||
/** Proxy class to copy a file locally in large chunks. */ | ||
class LocalCacheFile : public Storage | ||
{ | ||
public: | ||
LocalCacheFile (Storage *base); | ||
~LocalCacheFile (void); | ||
|
||
using Storage::read; | ||
using Storage::write; | ||
|
||
virtual bool prefetch (const IOPosBuffer *what, IOSize n); | ||
virtual IOSize read (void *into, IOSize n); | ||
virtual IOSize read (void *into, IOSize n, IOOffset pos); | ||
virtual IOSize readv (IOBuffer *into, IOSize n); | ||
virtual IOSize readv (IOPosBuffer *into, IOSize n); | ||
virtual IOSize write (const void *from, IOSize n); | ||
virtual IOSize write (const void *from, IOSize n, IOOffset pos); | ||
virtual IOSize writev (const IOBuffer *from, IOSize n); | ||
virtual IOSize writev (const IOPosBuffer *from, IOSize n); | ||
|
||
virtual IOOffset position (IOOffset offset, Relative whence = SET); | ||
virtual void resize (IOOffset size); | ||
virtual void flush (void); | ||
virtual void close (void); | ||
|
||
private: | ||
void cache (IOOffset start, IOOffset end); | ||
|
||
IOOffset image_; | ||
std::vector<bool> present_; | ||
File *file_; | ||
Storage *storage_; | ||
}; | ||
|
||
#endif // STORAGE_FACTORY_LOCAL_CACHE_FILE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
#include "Utilities/StorageFactory/interface/LocalCacheFile.h" | ||
#include "Utilities/StorageFactory/interface/File.h" | ||
#include "FWCore/Utilities/interface/EDMException.h" | ||
#include <utility> | ||
#include <iostream> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <sys/mman.h> | ||
#include <errno.h> | ||
|
||
static const IOOffset CHUNK_SIZE = 128*1024*1024; | ||
|
||
static void | ||
nowrite(const char *why) | ||
{ | ||
throw cms::Exception("LocalCacheFile") | ||
<< "Cannot change file but operation '" << why << "' was called"; | ||
} | ||
|
||
|
||
LocalCacheFile::LocalCacheFile(Storage *base) | ||
: image_(base->size()), | ||
file_(0), | ||
storage_(base) | ||
{ | ||
present_.resize((image_ + CHUNK_SIZE - 1) / CHUNK_SIZE, false); | ||
|
||
std::string pattern("/tmp"); | ||
if (char *p = getenv("TMPDIR")) | ||
pattern = p; | ||
pattern += "/cmssw-shadow-XXXXXX"; | ||
|
||
std::vector<char> temp(pattern.c_str(), pattern.c_str()+pattern.size()+1); | ||
int fd = mkstemp(&temp[0]); | ||
if (fd == -1) | ||
throw cms::Exception("LocalCacheFile") | ||
<< "Cannot create temporary file '" << pattern << "': " | ||
<< strerror(errno) << " (error " << errno << ")"; | ||
|
||
unlink(&temp[0]); | ||
file_ = new File(fd); | ||
file_->resize(image_); | ||
} | ||
|
||
LocalCacheFile::~LocalCacheFile(void) | ||
{ | ||
delete file_; | ||
delete storage_; | ||
} | ||
|
||
void | ||
LocalCacheFile::cache(IOOffset start, IOOffset end) | ||
{ | ||
start = (start / CHUNK_SIZE) * CHUNK_SIZE; | ||
end = std::min(end, image_); | ||
while (start < end) | ||
{ | ||
IOSize nread = 0; | ||
IOSize index = start / CHUNK_SIZE; | ||
IOSize len = std::min(image_ - start, CHUNK_SIZE); | ||
if (! present_[index]) | ||
{ | ||
void *window = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, file_->fd(), start); | ||
if (window == MAP_FAILED) | ||
throw cms::Exception("LocalCacheFile") | ||
<< "Unable to map a window of local cache file: " | ||
<< strerror(errno) << " (error " << errno << ")"; | ||
|
||
try | ||
{ | ||
nread = storage_->read(window, len, start); | ||
} | ||
catch (cms::Exception &e) | ||
{ | ||
munmap(window, len); | ||
throw cms::Exception("LocalCacheFile") | ||
<< "Unable to cache " << len << " byte file segment at " << start | ||
<< ": " << e.what(); | ||
} | ||
|
||
munmap(window, len); | ||
|
||
if (nread != len) | ||
throw cms::Exception("LocalCacheFile") | ||
<< "Unable to cache " << len << " byte file segment at " << start | ||
<< ": got only " << nread << " bytes back"; | ||
|
||
present_[index] = true; | ||
} | ||
|
||
start += len; | ||
} | ||
} | ||
|
||
IOSize | ||
LocalCacheFile::read(void *into, IOSize n) | ||
{ | ||
IOOffset here = file_->position(); | ||
cache(here, here + n); | ||
|
||
return file_->read(into, n); | ||
} | ||
|
||
IOSize | ||
LocalCacheFile::read(void *into, IOSize n, IOOffset pos) | ||
{ | ||
cache(pos, pos + n); | ||
return file_->read(into, n, pos); | ||
} | ||
|
||
IOSize | ||
LocalCacheFile::readv(IOBuffer *into, IOSize n) | ||
{ | ||
IOOffset start = file_->position(); | ||
IOOffset end = start; | ||
for (IOSize i = 0; i < n; ++i) | ||
end += into[i].size(); | ||
cache(start, end); | ||
|
||
return file_->readv(into, n); | ||
} | ||
|
||
IOSize | ||
LocalCacheFile::readv(IOPosBuffer *into, IOSize n) | ||
{ | ||
for (IOSize i = 0; i < n; ++i) | ||
{ | ||
IOOffset start = into[i].offset(); | ||
IOOffset end = start + into[i].size(); | ||
cache(start, end); | ||
} | ||
|
||
return storage_->readv(into, n); | ||
} | ||
|
||
IOSize | ||
LocalCacheFile::write(const void *from, IOSize n) | ||
{ nowrite("write"); return 0; } | ||
|
||
IOSize | ||
LocalCacheFile::write(const void *from, IOSize n, IOOffset pos) | ||
{ nowrite("write"); return 0; } | ||
|
||
IOSize | ||
LocalCacheFile::writev(const IOBuffer *from, IOSize n) | ||
{ nowrite("writev"); return 0; } | ||
|
||
IOSize | ||
LocalCacheFile::writev(const IOPosBuffer *from, IOSize n) | ||
{ nowrite("writev"); return 0; } | ||
|
||
IOOffset | ||
LocalCacheFile::position(IOOffset offset, Relative whence) | ||
{ return file_->position(offset, whence); } | ||
|
||
void | ||
LocalCacheFile::resize(IOOffset size) | ||
{ nowrite("resize"); } | ||
|
||
void | ||
LocalCacheFile::flush(void) | ||
{ nowrite("flush"); } | ||
|
||
void | ||
LocalCacheFile::close(void) | ||
{ | ||
storage_->close(); | ||
file_->close(); | ||
} | ||
|
||
bool | ||
LocalCacheFile::prefetch(const IOPosBuffer *what, IOSize n) | ||
{ | ||
for (IOSize i = 0; i < n; ++i) | ||
{ | ||
IOOffset start = what[i].offset(); | ||
IOOffset end = start + what[i].size(); | ||
cache(start, end); | ||
} | ||
|
||
return file_->prefetch(what, n); | ||
} |