forked from pkucoin/yfs-class
-
Notifications
You must be signed in to change notification settings - Fork 0
/
yfs_client.h
167 lines (146 loc) · 3.96 KB
/
yfs_client.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef yfs_client_h
#define yfs_client_h
#include <string>
//#include "yfs_protocol.h"
#include "extent_client.h"
#include <vector>
#include "lock_protocol.h"
#include "lock_client.h"
#include <random>
#include <climits>
#include "lock_client_cache.h"
class lock_release_extent : public lock_release_user {
private:
extent_client *ec;
public:
lock_release_extent(extent_client *_ec) : ec(_ec) {}
void dorelease(lock_protocol::lockid_t lid)
{
ec->flush(lid);
}
};
class yfs_client {
extent_client *ec;
lock_client *lc;
lock_release_user *lu;
public:
typedef unsigned long long inum;
enum xxstatus { OK, RPCERR, NOENT, IOERR, EXIST };
typedef int status;
struct fileinfo {
unsigned long long size;
unsigned long atime;
unsigned long mtime;
unsigned long ctime;
};
struct dirinfo {
unsigned long atime;
unsigned long mtime;
unsigned long ctime;
};
struct dirent {
std::string name;
yfs_client::inum inum;
};
class dirent_list {
public:
dirent_list(std::string buf)
{
unsigned int cur = 0;
while (cur < buf.size())
{
int start = ++cur;
while (cur < buf.size() && isdigit(buf[cur]))
{
++cur;
}
unsigned int len_name = n2i(buf.substr(start, cur - start));
start = ++cur;
while (cur < buf.size() && isdigit(buf[cur]))
{
++cur;
}
unsigned int len_inum = n2i(buf.substr(start, cur - start));
start = ++cur;
data[buf.substr(start, len_name)] = n2i(buf.substr(start + len_name, len_inum));
cur = start + len_name + len_inum;
}
}
bool match(std::string name)
{
return data.find(name) != data.end();
}
inum get(const char *name)
{
if (!match(name))
{
return -1;
}
return data[name];
}
void add(inum id, const char *name)
{
data[name] = id;
}
void remove(const char *name)
{
data.erase(name);
}
std::unordered_map<std::string, inum> get_map()
{
return data;
}
std::string to_string()
{
std::string ret = "";
for (const auto& kv : data)
{
std::string id = std::to_string(kv.second);
// format: @name.size@id.size@nameid
// eg. name="hehe" id=123 ret="@4@3@hehe123"
ret += separator + std::to_string(kv.first.size())
+ separator + std::to_string(id.size())
+ separator + kv.first + id;
}
return ret;
}
private:
std::unordered_map<std::string, inum> data;
const std::string separator = "@";
};
private:
static std::string filename(inum);
static inum n2i(std::string);
inum rand_inum(bool);
std::mt19937 generator;
std::uniform_int_distribution<int> uid;
public:
yfs_client(std::string, std::string);
bool isfile(inum);
bool isdir(inum);
int getfile(inum, fileinfo &);
int getdir(inum, dirinfo &);
yfs_client::status create(inum parent, const char *name, bool isdir, inum &ret_id);
yfs_client::status lookup(inum parent, const char *name, inum &ret_id);
yfs_client::status readdir(inum parent, std::unordered_map<std::string, inum>& ret_map);
yfs_client::status setattr(inum ino, unsigned int len);
yfs_client::status read(inum ino, std::size_t off, std::size_t len, std::string& data);
yfs_client::status write(inum ino, std::size_t off, std::size_t len, const char *data);
yfs_client::status unlink(inum parent, const char *name);
};
class raii_wrapper
{
private:
lock_client *lc;
yfs_client::inum ino;
public:
raii_wrapper(lock_client *lc_, yfs_client::inum ino_) : lc(lc_), ino(ino_)
{
lc->acquire(ino);
}
~raii_wrapper()
{
lc->release(ino);
}
};
#endif