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 | import copy file_template = { "isDirectory": False, "fileSize": 0, "childSize": 0, "childQuota": 0, "descendantQuota": 0, "descendants": {} } root_directory = { "isDirectory": True, "fileSize": 0, "childSize": 0, "childQuota": 0, "descendantQuota": 0, "descendants": {} } def filepath_resolver(filepath: str): fpArr = filepath.split('/') fpArr.pop(0) return fpArr def visit(filepath): if filepath == '/': return root_directory fpArr = filepath_resolver(filepath) fileIter = root_directory try: for file in fpArr: fileIter = fileIter["descendants"][file] except KeyError: return None return fileIter def checkQuotaLimit(fileIter, filesize, descendants = True, child = True): if descendants: if fileIter["descendantQuota"] != 0: # 检查后代文件配额 if fileIter["fileSize"] + filesize > fileIter["descendantQuota"]: return False if child: if fileIter["childQuota"] != 0: # 检查孩子文件配额 if fileIter["childSize"] + filesize > fileIter["childQuota"]: return False return True def create(filepath, filesize, isDirectory = False): dstIter = visit(filepath) update_filesize = filesize if dstIter is not None: update_filesize -= dstIter["fileSize"] fpArr = filepath_resolver(filepath) fileIter = root_directory for i in range(len(fpArr)): file = fpArr[i] if file not in fileIter["descendants"].keys(): # 无该目录/文件 curFile = copy.deepcopy(file_template) if i != len(fpArr) - 1: # 非末端文件 if not checkQuotaLimit(fileIter, update_filesize, True, False): return False curFile["isDirectory"] = True else: # 末端文件 if not checkQuotaLimit(fileIter, update_filesize): return False curFile["isDirectory"] = isDirectory curFile["fileSize"] = filesize fileIter["descendants"][file] = curFile else: # 存在该目录/文件 curFile = fileIter["descendants"][file] if i != len(fpArr) - 1: # 非末端文件 if not curFile["isDirectory"]: # 欲进入的新目录文件与普通文件重名 return False else: if not checkQuotaLimit(fileIter, update_filesize, True, False): return False else: # 末端文件 if curFile["isDirectory"] != isDirectory: # 欲创建的同名新文件与旧文件类型冲突 return False else: # 文件已存在,替换文件大小 if not checkQuotaLimit(fileIter, update_filesize): return False curFile["fileSize"] = filesize fileIter = fileIter["descendants"][file] fileIter = root_directory for i in range(len(fpArr)): file = fpArr[i] fileIter["fileSize"] += update_filesize if i == len(fpArr) - 1: fileIter["childSize"] += update_filesize fileIter = fileIter["descendants"][file] return True def remove(filepath): fpArr = filepath_resolver(filepath) dstIter = visit(filepath) if dstIter is None: return True fileIter = root_directory for file in fpArr: fileIter["fileSize"] -= dstIter["fileSize"] if fileIter["descendants"][file] == dstIter: if not dstIter["isDirectory"]: fileIter["childSize"] -= dstIter["fileSize"] break fileIter = fileIter["descendants"][file] fileIter["descendants"].pop(fpArr[-1]) return True def quota(filepath, child_quota, descendant_quota): dstIter = visit(filepath) if dstIter is None: return False if not dstIter["isDirectory"]: return False child_flag = child_quota == 0 or dstIter["childSize"] <= child_quota descendant_flag = descendant_quota == 0 or dstIter["fileSize"] <= descendant_quota if child_flag and descendant_flag: dstIter["childQuota"] = child_quota dstIter["descendantQuota"] = descendant_quota return True else: return False def main(): n = int(input()) for loop in range(n): cmd = input().split() result = False if cmd[0] == "C": result = create(cmd[1], int(cmd[2])) elif cmd[0] == "R": result = remove(cmd[1]) else: result = quota(cmd[1], int(cmd[2]), int(cmd[3])) if result: print("Y") else: print("N") # print(root_directory) if __name__ == '__main__': main() |
CSP 202012-3 带配额的文件系统
发表评论