文件缓存系统
请设计一个文件缓存系统,该文件缓存系统可以指定缓存的最大值(单位为字节)。
文件缓存系统有两种操作: 存储文件(put)和读取文件(get),操作命令为put fileName fileSize
或者get fileName
。存储文件是把文件放入文件缓存系统中;读取文件是从文件缓存系统中访问已存在的文件,如果文件不存在,则不作任何操作。
当缓存空间不足以存放新的文件时,根据规则删除文件,直到剩余空间满足新的文件大小为止,再存放新文件。具体的删除规则为文件访问过后,会更新文件的最近访问时间和总的访问次数,当缓存不够时,按照第一优先顺序为访问次数从少到多,第二顺序为最近访问时间从老到新的方式来删除文件。
输入描述:第一行为缓存最大值m(整数,取值范围为0< m <= 52428800);第二行为文件操作序列个数n(0 <= n <= 300000);从第三行起为文件操作序列,每个序列单独一行文件操作定义为”op file name
file size
"
class FileSystem:
def __init__(self, max_size):
self.max_size = max_size # 文件系统的缓存最大值
self.current_size = 0 # 文件系统的已用缓存
self.cache = {} # 各文件所占缓存空间
self.access_count = {} # 各文件的访问次数
self.access_time = {} # 各文件的最近访问时间
# 读取文件
def get(self, file_name):
# 如果文件不存在,则不作任何操作
if file_name not in self.cache:
return
# 如果文件存在,更新文件的访问次数和最近访问时间
# 将该文件的访问次数+1
self.access_count[file_name] += 1
# 将该文件名的最近访问时间更新为 目前的最大访问时间+1,以表示该文件名是最近访问的
self.access_time[file_name] = max(self.access_time.values()) + 1
# 存储文件
def put(self, file_name, file_size):
# 如果文件已存在,则不作任何操作
if file_name in self.cache:
return
# 如果缓存空间不足,按照删除规则删除文件,直到有足够的空间
while self.current_size + file_size > self.max_size:
file_to_delete = self._get_file_to_delete()
self._delete_file(file_to_delete)
# 存储文件,并更新缓存信息
self.cache[file_name] = file_size
self.current_size += file_size
self.access_count[file_name] = 0
self.access_time[file_name] = 0
# 按照删除规则选择要删除的文件
def _get_file_to_delete(self):
if not self.cache:
return None
sorted_files = sorted(
self.cache.keys(),
key=lambda x: (self.access_count[x], self.access_time[x])
)
return sorted_files[0]
# 删除文件,并更新缓存信息
def _delete_file(self, file_name):
if file_name is None:
return
file_size = self.cache.pop(file_name)
self.current_size -= file_size
del self.access_count[file_name]
del self.access_time[file_name]
# 输入输出
m = int(input('请输入缓存最大值:')) # 输入:缓存最大值
n = int(input('请输入文件操作序列个数:')) # 输入:文件操作序列个数
file_system = FileSystem(m) # 初始化文件系统
for _ in range(n):
op, file_name, file_size = input('请输入文件操作序列:').split() # 输入:文件操作序列
file_size = int(file_size)
if op == "put":
file_system.put(file_name, file_size)
elif op == "get":
file_system.get(file_name)