Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
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
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
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
43 changes: 43 additions & 0 deletions trunk/Utilities/StorageFactory/interface/LocalCacheFile.h
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
183 changes: 183 additions & 0 deletions trunk/Utilities/StorageFactory/src/LocalCacheFile.cc
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);
}

0 comments on commit 880f8ae

Please sign in to comment.