#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
using namespace std;
struct File;
struct Fold;
struct File
{
#define normal 1
#define uploading 2
Fold *parent;
int fileSize;
int fileState;
};
struct Fold
{
#define normal 1
#define uploading 2
int foldState;
int foldSize;
Fold *parent;
map<string, File> fileMap;
map<string, Fold> foldMap;
};
struct User
{
#define uploadUser 1
#define downloadUser 2
#define guest 3
#define scan 1
#define download 2
#define upload 3
int userType;
int userState; //用户状态(用户正在执行的操作)
Fold *userPosition; //用户当前所处的位置(即用户正在浏览的文件夹)
};
struct TaskFile
{
string userName;
File *file;
int lastSize;
};
struct TaskFold
{
string userName;
Fold *fold;
int lastSize;
};
struct FTP
{
int maxUserNumber;
int maxServerFlux;
int maxUserFlux;
Fold Root;
map<string, User> userMap;
vector<TaskFile> taskFile;
vector<TaskFold> taskFold;
bool connect(string userName, int State)
{
if (userMap.find(userName) == userMap.end())
{
if (userMap.size() >= maxUserNumber)
{
return false;
}
User user;
user.userType = State;
user.userState = scan;
user.userPosition = &Root;
userMap[userName] = user;
return true;
}
else
{
return false;
}
}
bool quit(string userName)
{
if (userMap.find(userName) != userMap.end())
{
userMap.erase(userName);
vector<TaskFile> tmp;
for (int i = 0; i < taskFile.size(); i++)
{
if (!(taskFile[i].userName == userName))
tmp.push_back(taskFile[i]);
}
taskFile = tmp;
vector<TaskFold> tmp2;
for (int i = 0; i < taskFold.size(); i++)
{
if (!(taskFold[i].userName == userName))
tmp2.push_back(taskFold[i]);
}
taskFold = tmp2;
return true;
}
else
{
return false;
}
}
bool cd(string userName, string foldName)
{
if (userMap.find(userName) == userMap.end())
{
return false;
}
if (userMap[userName].userPosition->foldMap.find(foldName) != userMap[userName].userPosition->foldMap.end())
{
if (userMap[userName].userPosition->foldMap[foldName].foldState == normal)
{
userMap[userName].userPosition = &userMap[userName].userPosition->foldMap[foldName];
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
bool cd_back(string userName)
{
if (userMap.find(userName) == userMap.end())
{
return false;
}
if (userMap[userName].userPosition->parent != NULL)
{
userMap[userName].userPosition = userMap[userName].userPosition->parent;
return true;
}
else
{
return false;
}
}
bool startdownload(string userName, string fileName)
{
if (userMap.find(userName) == userMap.end())
{
return false;
}
if (userMap[userName].userType != downloadUser)
{
return false;
}
if (userMap[userName].userState != scan)
{
return false;
}
if (userMap[userName].userPosition->fileMap.find(fileName) == userMap[userName].userPosition->fileMap.end() && userMap[userName].userPosition->foldMap.find(fileName) == userMap[userName].userPosition->foldMap.end())
{
return false;
}
if (userMap[userName].userPosition->fileMap.find(fileName) != userMap[userName].userPosition->fileMap.end())
{
if (userMap[userName].userPosition->fileMap[fileName].fileState == normal)
{
TaskFile task;
task.userName = userName;
task.file = &userMap[userName].userPosition->fileMap[fileName];
task.lastSize = userMap[userName].userPosition->fileMap[fileName].fileSize;
taskFile.push_back(task);
userMap[userName].userState = download;
return true;
}
else
{
return false;
}
}
if (userMap[userName].userPosition->foldMap.find(fileName) != userMap[userName].userPosition->foldMap.end())
{
if (userMap[userName].userPosition->foldMap[fileName].foldState == normal)
{
TaskFold task;
task.userName = userName;
task.fold = &userMap[userName].userPosition->foldMap[fileName];
task.lastSize = userMap[userName].userPosition->foldMap[fileName].foldSize;
taskFold.push_back(task);
userMap[userName].userState = download;
return true;
}
else
{
return false;
}
}
}
bool startupload(string userName, string fileName, int size)
{
if (userMap.find(userName) == userMap.end())
{
return false;
}
if (userMap[userName].userType != uploadUser)
{
return false;
}
if (userMap[userName].userState != scan)
{
return false;
}
if (size == 0) //Fold
{
if (userMap[userName].userPosition->foldMap.find(fileName) != userMap[userName].userPosition->foldMap.end())
{
return false;
}
else
{
Fold newFold;
newFold.foldState = uploading;
newFold.foldSize = 0;
newFold.parent = userMap[userName].userPosition;
userMap[userName].userPosition->foldMap[fileName] = newFold;
return true;
}
}
else
{
if (userMap[userName].userPosition->fileMap.find(fileName) != userMap[userName].userPosition->fileMap.end())
{
return false;
}
else
{
File newFile;
newFile.fileSize = size;
newFile.fileState = uploading;
newFile.parent = userMap[userName].userPosition;
userMap[userName].userPosition->fileMap[fileName] = newFile;
TaskFile newtask;
newtask.userName = userName;
newtask.file = &userMap[userName].userPosition->fileMap[fileName];
newtask.lastSize = size;
taskFile.push_back(newtask);
//更新父文件夹大小
Fold *nowFold = userMap[userName].userPosition;
while (nowFold != NULL)
{
nowFold->foldSize += size;
nowFold->foldState = uploading;
nowFold = nowFold->parent;
}
userMap[userName].userState = upload;
return true;
}
}
return false;
}
} Server;
inline void init()
{
Server.Root.foldState = normal;
Server.Root.foldSize = 0;
Server.Root.parent = NULL;
cin >> Server.maxUserNumber >> Server.maxServerFlux >> Server.maxUserFlux;
Fold *nowfold = &Server.Root;
while (nowfold != NULL)
{
string filename;
cin >> filename;
if (filename == "-")
{
for (auto &i : nowfold->foldMap)
{
nowfold->foldSize += i.second.foldSize;
}
for (auto &i : nowfold->fileMap)
{
nowfold->foldSize += i.second.fileSize;
}
nowfold = nowfold->parent;
}
else
{
int size;
cin >> size;
if (size == 0) //Fold
{
Fold newFold;
newFold.foldState = normal;
newFold.foldSize = 0;
newFold.parent = nowfold;
nowfold->foldMap[filename] = newFold;
nowfold = &nowfold->foldMap[filename];
}
else //File
{
File newFile;
newFile.fileSize = size;
newFile.fileState = normal;
newFile.parent = nowfold;
nowfold->fileMap[filename] = newFile;
}
}
}
return;
}
void unlock_fold(Fold *nowfold)
{
if (nowfold == NULL)
{
return;
}
for (auto &i : nowfold->foldMap)
{
if (i.second.foldState != normal)
{
return;
}
}
for (auto &i : nowfold->fileMap)
{
if (i.second.fileState != normal)
{
return;
}
}
nowfold->foldState = normal;
//向上解锁
unlock_fold(nowfold->parent);
}
int nowTime = 0;
inline void time_loop(int to)
{
while (nowTime < to)
{
if (int(Server.taskFile.size() + Server.taskFold.size()) == 0) //没有任务
{
nowTime = to;
return;
}
nowTime++;
int singleflux = min(Server.maxServerFlux / int(Server.taskFile.size() + Server.taskFold.size()), Server.maxUserFlux);
vector<TaskFile> Tmp;
for (auto &i : Server.taskFile)
{
i.lastSize -= singleflux;
if (i.lastSize <= 0)
{
i.file->fileState = normal;
Server.userMap[i.userName].userState = scan;
unlock_fold(i.file->parent);
}
else
Tmp.push_back(i);
}
Server.taskFile = Tmp;
vector<TaskFold> Tmp2;
for (auto &i : Server.taskFold)
{
i.lastSize -= singleflux;
if (i.lastSize <= 0)
{
i.fold->foldState = normal;
Server.userMap[i.userName].userState = scan;
unlock_fold(i.fold->parent);
}
else
Tmp2.push_back(i);
}
Server.taskFold = Tmp2;
}
}
inline void run()
{
while (true)
{
int time;
string operUser, opt;
cin >> time >> operUser >> opt;
time_loop(time);
if (opt == "")
{
break;
}
if (opt == "connect")
{
int userType;
cin >> userType;
if (Server.connect(operUser, userType))
{
cout << "success" << endl;
}
else
{
cout << "unsuccess" << endl;
}
}
else if (opt == "quit")
{
if (Server.quit(operUser))
{
cout << "success" << endl;
}
else
{
cout << "unsuccess" << endl;
}
}
else if (opt == "cd")
{
string foldname;
cin >> foldname;
if (Server.cd(operUser, foldname))
{
cout << "success" << endl;
}
else
{
cout << "unsuccess" << endl;
}
}
else if (opt == "cd..")
{
if (Server.cd_back(operUser))
{
cout << "success" << endl;
}
else
{
cout << "unsuccess" << endl;
}
}
else if (opt == "download")
{
string optname;
cin >> optname;
if (Server.startdownload(operUser, optname))
{
cout << "success" << endl;
}
else
{
cout << "unsuccess" << endl;
}
}
else if (opt == "upload")
{
string optname;
int size;
cin >> optname >> size;
if (Server.startupload(operUser, optname, size))
{
cout << "success" << endl;
}
else
{
cout << "unsuccess" << endl;
}
}
}
}
int main()
{
init();
run();
return 0;
}