15 #include <boost/algorithm/string.hpp>
16 #include <boost/foreach.hpp>
17 #include <boost/lexical_cast.hpp>
18 #include <boost/uuid/uuid_io.hpp>
19 #include <boost/uuid/random_generator.hpp>
20 #include <boost/filesystem.hpp>
21 #include <gutil/strings/substitute.h>
22 #include <gutil/strings/join.h>
29 DEFINE_string(scratch_dirs,
"/tmp",
"Writable scratch directories");
33 using boost::algorithm::is_any_of;
34 using boost::algorithm::split;
35 using boost::algorithm::token_compress_on;
37 using boost::uuids::random_generator;
38 using namespace strings;
44 bool TmpFileMgr::initialized_;
45 vector<string> TmpFileMgr::tmp_dirs_;
48 DCHECK(!initialized_);
49 string tmp_dirs_spec = FLAGS_scratch_dirs;
50 vector<string> all_tmp_dirs;
51 split(all_tmp_dirs, tmp_dirs_spec, is_any_of(
","), token_compress_on);
52 vector<bool> is_tmp_dir_on_disk(DiskInfo::num_disks(),
false);
56 for (
int i = 0; i < all_tmp_dirs.size(); ++i) {
57 path tmp_path(trim_right_copy_if(all_tmp_dirs[i], is_any_of(
"/")));
62 int disk_id = DiskInfo::disk_id(tmp_path.c_str());
63 if (disk_id < 0 || !is_tmp_dir_on_disk[disk_id]) {
68 LOG(WARNING) <<
"Filesystem containing scratch directory " << tmp_path
72 if (disk_id >= 0) is_tmp_dir_on_disk[disk_id] =
true;
74 tmp_dirs_.push_back(create_dir_path.string());
78 Status status = FileSystemUtil::CreateDirectories(tmp_dirs_);
80 LOG (INFO) <<
"Created the following scratch dirs:" << JoinStrings(tmp_dirs_,
" ");
83 FileSystemUtil::RemovePaths(tmp_dirs_);
91 DCHECK_LT(tmp_device_id, tmp_dirs_.size());
94 string unique_name = lexical_cast<
string>(random_generator()());
95 stringstream file_name;
96 file_name <<
PrintId(query_id) <<
"_" << unique_name;
97 path new_file_path(tmp_dirs_[tmp_device_id]);
98 new_file_path /= file_name.str();
100 *new_file =
new File(new_file_path.string());
104 TmpFileMgr::File::File(
const string&
path)
111 DCHECK_GT(write_size, 0);
112 DCHECK_GE(current_size_, current_offset_);
113 *offset = current_offset_;
115 if (current_size_ == 0) {
121 current_offset_ += write_size;
122 if (current_offset_ > current_size_) {
123 int64_t trunc_len = current_offset_ + write_size;
125 current_size_ = trunc_len;
128 DCHECK_GE(current_size_, current_offset_);
static Status CreateFile(const std::string &file_path)
Create a file at the specified path.
string path("/usr/lib/sasl2:/usr/lib64/sasl2:/usr/local/lib/sasl2:/usr/lib/x86_64-linux-gnu/sasl2")
const TUniqueId & query_id() const
Status AllocateSpace(int64_t write_size, int64_t *offset)
#define RETURN_IF_ERROR(stmt)
some generally useful macros
string PrintId(const TUniqueId &id, const string &separator)
static Status RemovePaths(const std::vector< std::string > &directories)
Remove the specified paths and their enclosing files/directories.
DEFINE_string(scratch_dirs,"/tmp","Writable scratch directories")
const uint64_t AVAILABLE_SPACE_THRESHOLD_MB
uint8_t offset[7 *64-sizeof(uint64_t)]
static Status ResizeFile(const std::string &file_path, int64_t trunc_len)
Resize a file to a specified length - uses unistd truncate().
const string TMP_SUB_DIR_NAME
static int disk_id(const char *path)