21
21
#include " common/exception.h"
22
22
#include " common/logger.h"
23
23
#include " storage/disk/disk_manager.h"
24
+ #include < unistd.h>
25
+ #include < fcntl.h>
24
26
25
27
namespace bustub {
26
28
@@ -38,40 +40,32 @@ DiskManager::DiskManager(const std::string &db_file) : file_name_(db_file) {
38
40
}
39
41
log_name_ = file_name_.substr (0 , n) + " .log" ;
40
42
41
- log_io_.open (log_name_, std::ios::binary | std::ios::in | std::ios::app | std::ios::out);
42
- // directory or file does not exist
43
- if (!log_io_.is_open ()) {
44
- log_io_.clear ();
45
- // create a new file
46
- log_io_.open (log_name_, std::ios::binary | std::ios::trunc | std::ios::out | std::ios::in);
47
- if (!log_io_.is_open ()) {
48
- throw Exception (" can't open dblog file" );
49
- }
43
+ // Open log file using file descriptor
44
+ log_fd_ = open (log_name_.c_str (), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
45
+ if (log_fd_ < 0 ) {
46
+ throw Exception (" can't open log file" );
50
47
}
51
48
52
- std::scoped_lock scoped_db_io_latch (db_io_latch_);
53
- db_io_.open (db_file, std::ios::binary | std::ios::in | std::ios::out);
54
- // directory or file does not exist
55
- if (!db_io_.is_open ()) {
56
- db_io_.clear ();
57
- // create a new file
58
- db_io_.open (db_file, std::ios::binary | std::ios::trunc | std::ios::out | std::ios::in);
59
- if (!db_io_.is_open ()) {
60
- throw Exception (" can't open db file" );
61
- }
49
+ // Open db file using file descriptor
50
+ db_fd_ = open (db_file.c_str (), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
51
+ if (db_fd_ < 0 ) {
52
+ close (log_fd_);
53
+ throw Exception (" can't open db file" );
62
54
}
55
+
63
56
buffer_used = nullptr ;
64
57
}
65
58
59
+
66
60
/* *
67
61
* Close all file streams
68
62
*/
69
63
void DiskManager::ShutDown () {
70
64
{
71
65
std::scoped_lock scoped_db_io_latch (db_io_latch_);
72
- db_io_. close ();
66
+ close (db_fd_); // Close the db file descriptor
73
67
}
74
- log_io_. close ();
68
+ close (log_fd_); // Close the log file descriptor
75
69
}
76
70
77
71
/* *
@@ -80,19 +74,16 @@ void DiskManager::ShutDown() {
80
74
void DiskManager::WritePage (page_id_t page_id, const char *page_data) {
81
75
std::scoped_lock scoped_db_io_latch (db_io_latch_);
82
76
size_t offset = static_cast <size_t >(page_id) * BUSTUB_PAGE_SIZE;
83
- // set write cursor to offset
84
- num_writes_ += 1 ;
85
- db_io_.seekp (offset);
86
- db_io_.write (page_data, BUSTUB_PAGE_SIZE);
87
- // check for I/O error
88
- if (db_io_.bad ()) {
89
- LOG_DEBUG (" I/O error while writing" );
77
+
78
+ ssize_t bytes_written = pwrite (db_fd_, page_data, BUSTUB_PAGE_SIZE, offset);
79
+ if (bytes_written == -1 ) {
80
+ LOG_DEBUG (" I/O error while writing with pwrite" );
90
81
return ;
91
82
}
92
- // needs to flush to keep disk file in sync
93
- db_io_.flush ();
83
+ num_writes_ += 1 ;
94
84
}
95
85
86
+
96
87
/* *
97
88
* Read the contents of the specified page into the given memory area
98
89
*/
@@ -102,22 +93,18 @@ void DiskManager::ReadPage(page_id_t page_id, char *page_data) {
102
93
// check if read beyond file length
103
94
if (offset > GetFileSize (file_name_)) {
104
95
LOG_DEBUG (" I/O error reading past end of file" );
105
- // std::cerr << "I/O error while reading" << std::endl;
106
96
} else {
107
- // set read cursor to offset
108
- db_io_.seekp (offset);
109
- db_io_.read (page_data, BUSTUB_PAGE_SIZE);
110
- if (db_io_.bad ()) {
111
- LOG_DEBUG (" I/O error while reading" );
97
+
98
+ ssize_t bytes_read = pread (db_fd_, page_data, BUSTUB_PAGE_SIZE, offset);
99
+ if (bytes_read == -1 ) {
100
+ LOG_DEBUG (" I/O error while reading with pread" );
112
101
return ;
113
102
}
114
- // if file ends before reading BUSTUB_PAGE_SIZE
115
- int read_count = db_io_. gcount ();
116
- if (read_count < BUSTUB_PAGE_SIZE) {
103
+
104
+ // If file ends before reading BUSTUB_PAGE_SIZE
105
+ if (bytes_read < BUSTUB_PAGE_SIZE) {
117
106
LOG_DEBUG (" Read less than a page" );
118
- db_io_.clear ();
119
- // std::cerr << "Read less than a page" << std::endl;
120
- memset (page_data + read_count, 0 , BUSTUB_PAGE_SIZE - read_count);
107
+ memset (page_data + bytes_read, 0 , BUSTUB_PAGE_SIZE - bytes_read);
121
108
}
122
109
}
123
110
}
@@ -127,7 +114,6 @@ void DiskManager::ReadPage(page_id_t page_id, char *page_data) {
127
114
* Only return when sync is done, and only perform sequence write
128
115
*/
129
116
void DiskManager::WriteLog (char *log_data, int size) {
130
- // enforce swap log buffer
131
117
assert (log_data != buffer_used);
132
118
buffer_used = log_data;
133
119
@@ -137,48 +123,35 @@ void DiskManager::WriteLog(char *log_data, int size) {
137
123
138
124
flush_log_ = true ;
139
125
140
- if (flush_log_f_ != nullptr ) {
141
- // used for checking non-blocking flushing
142
- assert (flush_log_f_->wait_for (std::chrono::seconds (10 )) == std::future_status::ready);
143
- }
144
-
145
126
num_flushes_ += 1 ;
146
- // sequence write
147
- log_io_.write (log_data, size);
148
-
149
- // check for I/O error
150
- if (log_io_.bad ()) {
151
- LOG_DEBUG (" I/O error while writing log" );
127
+ ssize_t bytes_written = pwrite (log_fd_, log_data, size, 0 ); // Always appending
128
+ if (bytes_written == -1 ) {
129
+ LOG_DEBUG (" I/O error while writing log with pwrite" );
152
130
return ;
153
131
}
154
- // needs to flush to keep disk file in sync
155
- log_io_.flush ();
132
+
156
133
flush_log_ = false ;
157
134
}
158
135
136
+
159
137
/* *
160
138
* Read the contents of the log into the given memory area
161
139
* Always read from the beginning and perform sequence read
162
140
* @return: false means already reach the end
163
141
*/
164
- auto DiskManager::ReadLog (char *log_data, int size, int offset) -> bool {
142
+ bool DiskManager::ReadLog (char *log_data, int size, int offset) {
165
143
if (offset >= GetFileSize (log_name_)) {
166
- // LOG_DEBUG("end of log file");
167
- // LOG_DEBUG("file size is %d", GetFileSize(log_name_));
168
144
return false ;
169
145
}
170
- log_io_.seekp (offset);
171
- log_io_.read (log_data, size);
172
146
173
- if (log_io_.bad ()) {
174
- LOG_DEBUG (" I/O error while reading log" );
147
+ ssize_t bytes_read = pread (log_fd_, log_data, size, offset);
148
+ if (bytes_read == -1 ) {
149
+ LOG_DEBUG (" I/O error while reading log with pread" );
175
150
return false ;
176
151
}
177
- // if log file ends before reading "size"
178
- int read_count = log_io_.gcount ();
179
- if (read_count < size) {
180
- log_io_.clear ();
181
- memset (log_data + read_count, 0 , size - read_count);
152
+
153
+ if (bytes_read < size) {
154
+ memset (log_data + bytes_read, 0 , size - bytes_read);
182
155
}
183
156
184
157
return true ;
0 commit comments