Untitled
unknown
c_cpp
2 years ago
8.0 kB
17
Indexable
struct User {
int capacity;
int used;
User(){}
User(int capacity) : capacity(capacity), used(0) {}
bool canAddFile(int fileSize) {
return used + fileSize <= capacity;
}
void addFile(int fileSize) {
used += fileSize;
}
void removeFile(int fileSize) {
used -= fileSize;
}
int remainingCapacity() {
return capacity - used;
}
};
struct CloudStorage {
std::unordered_map<std::string, int> files; // File name to size mapping
std::unordered_map<std::string, std::string> fileOwners; // File name to owner mapping
std::unordered_map<std::string, User> users; // User ID to User object mapping
std::map<int, std::set<std::string>, std::greater<int>> sizeToFileNames; // Size to file names mapping
std::unordered_map<std::string, std::vector<std::pair<std::string, int>>> backups;
CloudStorage() {
// Adding an admin user with unlimited capacity
users["admin"] = User(INT_MAX);
}
std::string addUser(const std::string& userId, int capacity) {
if (users.find(userId) != users.end()) {
return "false";
}
users[userId] = User(capacity);
//cout << users[userId].capacity << '\n';
return "true";
}
std::string addFileBy(const std::string& userId, const std::string& fileName, int size) {
if (files.find(fileName) != files.end() || users.find(userId) == users.end() || !users[userId].canAddFile(size)) {
return "";
}
files[fileName] = size;
fileOwners[fileName] = userId;
sizeToFileNames[size].insert(fileName);
users[userId].addFile(size);
cout << users[userId].capacity << '\n';
return std::to_string(users[userId].remainingCapacity());
}
std::string mergeUsers(const std::string& userId1, const std::string& userId2) {
if (userId1 == userId2 || users.find(userId1) == users.end() || users.find(userId2) == users.end()) {
return "";
}
users[userId1].capacity += users[userId2].capacity;
for (const auto& [fileName, size] : files) {
if (fileOwners[fileName] == userId2) {
fileOwners[fileName] = userId1;
users[userId1].addFile(size);
users[userId2].removeFile(size);
}
}
int remainingCapacity = users[userId1].remainingCapacity();
users.erase(userId2);
return std::to_string(remainingCapacity);
}
std::string addFile(const std::string& name, int size) {
if (files.find(name) != files.end()) {
return "false";
}
files[name] = size;
fileOwners[name] = "admin"; // Associate the file with the admin user
sizeToFileNames[size].insert(name);
// No need to update the admin's used capacity since it's unlimited
return "true";
}
std::string getFileSize(const std::string& name) {
auto it = files.find(name);
if (it != files.end()) {
return std::to_string(it->second);
}
return "";
}
std::string deleteFile(const std::string& name) {
auto it = files.find(name);
if (it != files.end()) {
int fileSize = it->second;
std::string size = std::to_string(fileSize);
sizeToFileNames[fileSize].erase(name);
if (sizeToFileNames[fileSize].empty()) {
sizeToFileNames.erase(fileSize);
}
// Find the owner of the file and update their used storage
auto ownerIt = fileOwners.find(name);
if (ownerIt != fileOwners.end()) {
std::string ownerId = ownerIt->second;
if (users.find(ownerId) != users.end()) {
users[ownerId].removeFile(fileSize);
}
fileOwners.erase(ownerIt);
}
files.erase(it);
return size;
}
return "";
}
std::string getNLargestWithPrefix(const std::string& prefix, int n) {
std::vector<std::pair<std::string, int>> matchingFiles;
for (const auto& [size, names] : sizeToFileNames) {
for (const auto& name : names) {
if (name.substr(0, prefix.length()) == prefix) {
matchingFiles.emplace_back(name, size);
if (matchingFiles.size() == n) break;
}
}
if (matchingFiles.size() == n) break;
}
std::sort(matchingFiles.begin(), matchingFiles.end(), [](const auto& a, const auto& b) {
return a.second == b.second ? a.first < b.first : a.second > b.second;
});
std::string result;
for (const auto& [name, size] : matchingFiles) {
if (!result.empty()) result += ", ";
result += name + "(" + std::to_string(size) + ")";
}
return result;
}
std::string backupUser(const std::string& userId) {
if (users.find(userId) == users.end()) {
return ""; // User does not exist
}
std::vector<std::pair<std::string, int>>& userBackup = backups[userId];
userBackup.clear(); // Clear existing backup
for (const auto& [fileName, owner] : fileOwners) {
if (owner == userId) {
userBackup.emplace_back(fileName, files[fileName]);
}
}
return std::to_string(userBackup.size());
}
// RESTORE_USER implementation
std::string restoreUser(const std::string& userId) {
if (users.find(userId) == users.end()) {
return ""; // User does not exist
}
// First, delete all current files owned by the user
std::vector<std::string> filesToDelete;
for (const auto& [fileName, owner] : fileOwners) {
if (owner == userId) {
filesToDelete.push_back(fileName);
}
}
for (const auto& fileName : filesToDelete) {
deleteFile(fileName);
}
// Now, proceed with the restoration from the backup
if (backups.find(userId) == backups.end()) {
return "0"; // No backup exists, so nothing is restored
}
int restoredFilesCount = 0;
for (const auto& [fileName, size] : backups[userId]) {
if (files.find(fileName) == files.end()) {
// Restore file if it does not exist
files[fileName] = size;
fileOwners[fileName] = userId;
sizeToFileNames[size].insert(fileName);
users[userId].addFile(size);
restoredFilesCount++;
}
// If file with same name exists, it's ignored
}
return std::to_string(restoredFilesCount);
}
};
vector<string> solution(vector<vector<string>> queries) {
CloudStorage storage;
vector<string>ans;
for(auto q: queries){
auto op = q[0];
if(op == "ADD_FILE"){
ans.push_back(storage.addFile(q[1], stoi(q[2])));
}
else if(op == "GET_FILE_SIZE"){
ans.push_back(storage.getFileSize(q[1]));
}
else if(op == "GET_N_LARGEST"){
ans.push_back(storage.getNLargestWithPrefix(q[1], stoi(q[2])));
}
else if(op == "ADD_USER"){
ans.push_back(storage.addUser(q[1], stoi(q[2])));
}
else if(op == "ADD_FILE_BY"){
ans.push_back(storage.addFileBy(q[1], q[2], stoi(q[3])));
}
else if(op == "MERGE_USER"){
ans.push_back(storage.mergeUsers(q[1], q[2]));
}
else if(op == "BACKUP_USER"){
ans.push_back(storage.backupUser(q[1]));
}
else if(op == "RESTORE_USER")
ans.push_back(storage.restoreUser(q[1]));
else{
ans.push_back(storage.deleteFile(q[1]));
}
}
return ans;
}
Editor is loading...
Leave a Comment