Add delete cache to testcases

This commit is contained in:
cuom1999 2021-06-01 15:34:42 -05:00
parent 4bce15b536
commit 8ac611f9f4
5 changed files with 76 additions and 66 deletions

View file

@ -1,11 +1,13 @@
import errno import errno
import os import os
from zipfile import BadZipFile, ZipFile
from django.core.validators import FileExtensionValidator from django.core.validators import FileExtensionValidator
from django.core.cache import cache
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from judge.utils.problem_data import ProblemDataStorage from judge.utils.problem_data import ProblemDataStorage, get_file_cachekey
__all__ = ['problem_data_storage', 'problem_directory_file', 'ProblemData', 'ProblemTestCase', 'CHECKERS'] __all__ = ['problem_data_storage', 'problem_directory_file', 'ProblemData', 'ProblemTestCase', 'CHECKERS']
@ -66,7 +68,16 @@ class ProblemData(models.Model):
self.__original_zipfile = self.zipfile self.__original_zipfile = self.zipfile
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.zipfile != self.__original_zipfile: if self.zipfile != self.__original_zipfile and self.__original_zipfile:
# Delete caches
try:
files = ZipFile(self.__original_zipfile.path).namelist()
for file in files:
cache_key = 'problem_archive:%s:%s' % (self.problem.code, get_file_cachekey(file))
cache.delete(cache_key)
except BadZipFile:
pass
self.__original_zipfile.delete(save=False) self.__original_zipfile.delete(save=False)
return super(ProblemData, self).save(*args, **kwargs) return super(ProblemData, self).save(*args, **kwargs)

View file

@ -2,14 +2,15 @@ import json
import os import os
import re import re
import shutil import shutil
import yaml import yaml
import zipfile
from django.conf import settings from django.conf import settings
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.core.cache import cache
VALIDATOR_TEMPLATE_PATH = 'validator_template/template.py' VALIDATOR_TEMPLATE_PATH = 'validator_template/template.py'
@ -232,3 +233,61 @@ class ProblemDataCompiler(object):
def generate(cls, *args, **kwargs): def generate(cls, *args, **kwargs):
self = cls(*args, **kwargs) self = cls(*args, **kwargs)
self.compile() self.compile()
def get_visible_content(data):
data = data or b''
data = data.replace(b'\r\n', b'\r').replace(b'\r', b'\n')
data = data.decode('utf-8')
if (len(data) > settings.TESTCASE_VISIBLE_LENGTH):
data = data[:settings.TESTCASE_VISIBLE_LENGTH]
data += '.' * 3
return data
def get_file_cachekey(file):
return file.replace(' ', '===')
def get_problem_case(problem, files):
result = {}
uncached_files = []
for file in files:
cache_key = 'problem_archive:%s:%s' % (problem.code, get_file_cachekey(file))
qs = cache.get(cache_key)
if qs is None:
uncached_files.append(file)
else:
result[file] = qs
if not uncached_files:
return result
archive_path = os.path.join(settings.DMOJ_PROBLEM_DATA_ROOT,
str(problem.data_files.zipfile))
if not os.path.exists(archive_path):
raise Exception(
'archive file "%s" does not exist' % archive_path)
try:
archive = zipfile.ZipFile(archive_path, 'r')
except zipfile.BadZipfile:
raise Exception('bad archive: "%s"' % archive_path)
for file in uncached_files:
cache_key = 'problem_archive:%s:%s' % (problem.code, get_file_cachekey(file))
with archive.open(file) as f:
s = f.read(settings.TESTCASE_VISIBLE_LENGTH + 3)
# add this so there are no characters left behind (ex, 'á' = 2 utf-8 chars)
while True:
try:
s.decode('utf-8')
break
except UnicodeDecodeError:
s += f.read(1)
qs = get_visible_content(s)
cache.set(cache_key, qs, 86400)
result[file] = qs
return result

View file

@ -147,61 +147,3 @@ def hot_problems(duration, limit):
cache.set(cache_key, qs, 900) cache.set(cache_key, qs, 900)
return qs return qs
def get_visible_content(data):
data = data or b''
data = data.replace(b'\r\n', b'\r').replace(b'\r', b'\n')
data = data.decode('utf-8')
if (len(data) > settings.TESTCASE_VISIBLE_LENGTH):
data = data[:settings.TESTCASE_VISIBLE_LENGTH]
data += '.' * 3
return data
def get_cachekey_file(file):
return file.replace(' ', '===')
def get_problem_case(problem, files):
result = {}
uncached_files = []
for file in files:
cache_key = 'problem_archive:%s:%s' % (problem.code, get_cachekey_file(file))
qs = cache.get(cache_key)
if qs is None:
uncached_files.append(file)
else:
result['file'] = qs
if not uncached_files:
return result
archive_path = os.path.join(settings.DMOJ_PROBLEM_DATA_ROOT,
str(problem.data_files.zipfile))
if not os.path.exists(archive_path):
raise Exception(
'archive file "%s" does not exist' % archive_path)
try:
archive = zipfile.ZipFile(archive_path, 'r')
except zipfile.BadZipfile:
raise Exception('bad archive: "%s"' % archive_path)
for file in uncached_files:
cache_key = 'problem_archive:%s:%s' % (problem.code, get_cachekey_file(file))
with archive.open(file) as f:
s = f.read(settings.TESTCASE_VISIBLE_LENGTH + 3)
# add this so there are no characters left behind (ex, 'á' = 2 utf-8 chars)
while True:
try:
s.decode('utf-8')
break
except UnicodeDecodeError:
s += f.read(1)
qs = get_visible_content(s)
cache.set(cache_key, qs, 86400)
result[file] = qs
return result

View file

@ -43,7 +43,7 @@ from judge.utils.problems import get_result_data
from judge.utils.problems import user_authored_ids from judge.utils.problems import user_authored_ids
from judge.utils.problems import user_completed_ids from judge.utils.problems import user_completed_ids
from judge.utils.problems import user_editable_ids from judge.utils.problems import user_editable_ids
from judge.utils.problems import get_problem_case from judge.utils.problem_data import get_problem_case
from judge.utils.raw_sql import join_sql_subquery, use_straight_join from judge.utils.raw_sql import join_sql_subquery, use_straight_join
from judge.utils.views import DiggPaginatorMixin from judge.utils.views import DiggPaginatorMixin
from judge.utils.views import TitleMixin from judge.utils.views import TitleMixin
@ -172,7 +172,6 @@ class SubmissionStatus(SubmissionDetailBase):
submission = self.object submission = self.object
context['last_msg'] = event.last() context['last_msg'] = event.last()
context['batches'] = group_test_cases(submission.test_cases.all()) context['batches'] = group_test_cases(submission.test_cases.all())
print(context['batches'])
context['time_limit'] = submission.problem.time_limit context['time_limit'] = submission.problem.time_limit
contest = submission.contest_or_none contest = submission.contest_or_none

View file

@ -34,7 +34,6 @@ channels==2.4.0
channels-redis==2.4.2 channels-redis==2.4.2
docker docker
django-newsletter django-newsletter
python-memcached
netaddr netaddr
redis redis
lupa lupa