Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix MC which uses simgrid::xbt::string
[simgrid.git] / src / surf / FileImpl.cpp
1 /* Copyright (c) 2017. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "src/surf/FileImpl.hpp"
8 #include "src/surf/StorageImpl.hpp"
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_file, surf, "Logging specific to the SURF file module");
11 namespace simgrid {
12 namespace surf {
13
14 FileImpl::FileImpl(sg_storage_t st, std::string path, std::string mount) : path_(path), mount_point_(mount)
15 {
16   XBT_DEBUG("\tOpen file '%s'", path.c_str());
17   location_ = st->getImpl();
18   std::map<std::string, sg_size_t>* content = location_->getContent();
19   // if file does not exist create an empty file
20   try {
21     size_ = content->at(path);
22   } catch (std::out_of_range& unfound) {
23     size_ = 0;
24     content->insert({path, size_});
25     XBT_DEBUG("File '%s' was not found, file created.", path.c_str());
26   }
27 }
28
29 Action* FileImpl::read(sg_size_t size)
30 {
31   XBT_DEBUG("READ %s on disk '%s'", cname(), location_->cname());
32   if (current_position_ + size > size_) {
33     if (current_position_ > size_) {
34       size = 0;
35     } else {
36       size = size_ - current_position_;
37     }
38     current_position_ = size_;
39   } else
40     current_position_ += size;
41
42   return location_->read(size);
43 }
44
45 Action* FileImpl::write(sg_size_t size)
46 {
47   XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu'", cname(), location_->cname(), size, size_);
48
49   StorageAction* action = location_->write(size);
50   action->file_         = this;
51   /* Substract the part of the file that might disappear from the used sized on the storage element */
52   location_->usedSize_ -= (size_ - current_position_);
53   // If the storage is full before even starting to write
54   if (location_->usedSize_ >= location_->getSize()) {
55     action->setState(Action::State::failed);
56   }
57   return action;
58 }
59
60 int FileImpl::seek(sg_offset_t offset, int origin)
61 {
62   switch (origin) {
63     case SEEK_SET:
64       current_position_ = offset;
65       return 0;
66     case SEEK_CUR:
67       current_position_ += offset;
68       return 0;
69     case SEEK_END:
70       current_position_ = size_ + offset;
71       return 0;
72     default:
73       return -1;
74   }
75 }
76
77 int FileImpl::unlink()
78 {
79   /* Check if the file is on this storage */
80   if (location_->getContent()->find(path_) == location_->getContent()->end()) {
81     XBT_WARN("File %s is not on disk %s. Impossible to unlink", cname(), location_->cname());
82     return -1;
83   } else {
84     XBT_DEBUG("UNLINK %s on disk '%s'", cname(), location_->cname());
85     location_->usedSize_ -= size_;
86
87     // Remove the file from storage
88     location_->getContent()->erase(path_);
89
90     return 0;
91   }
92 }
93
94 void FileImpl::move(const char* fullpath)
95 {
96   /* Check if the new full path is on the same mount point */
97   if (not strncmp(mount_point_.c_str(), fullpath, mount_point_.size())) {
98     std::map<std::string, sg_size_t>* content = location_->getContent();
99     try { // src file exists
100       sg_size_t new_size = content->at(path_);
101       content->erase(path_);
102       std::string path = std::string(fullpath).substr(mount_point_.size(), strlen(fullpath));
103       content->insert({path.c_str(), new_size});
104       XBT_DEBUG("Move file from %s to %s, size '%llu'", path_.c_str(), fullpath, new_size);
105     } catch (std::out_of_range& unfound) {
106       XBT_WARN("File %s doesn't exist", path_.c_str());
107     }
108   } else {
109     XBT_WARN("New full path %s is not on the same mount point: %s.", fullpath, mount_point_.c_str());
110   }
111 }
112 }
113 }