/* * Copyright 2007 Zhang, Zheng <oldbig@gmail.com> * * This file is part of ZOJ. * * ZOJ is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either revision 3 of the License, or (at your option) any later revision. * * ZOJ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with ZOJ. if not, see * <http://www.gnu.org/licenses/>. */ package cn.edu.zju.acm.onlinejudge.util; import java.util.ArrayList; import java.util.List; import cn.edu.zju.acm.onlinejudge.bean.AbstractContest; import cn.edu.zju.acm.onlinejudge.bean.Problem; import cn.edu.zju.acm.onlinejudge.bean.Reference; import cn.edu.zju.acm.onlinejudge.bean.Submission; import cn.edu.zju.acm.onlinejudge.bean.enumeration.ReferenceType; import cn.edu.zju.acm.onlinejudge.bean.request.ProblemCriteria; import cn.edu.zju.acm.onlinejudge.persistence.ContestPersistence; import cn.edu.zju.acm.onlinejudge.persistence.PersistenceCreationException; import cn.edu.zju.acm.onlinejudge.persistence.PersistenceException; import cn.edu.zju.acm.onlinejudge.persistence.ProblemPersistence; import cn.edu.zju.acm.onlinejudge.persistence.ReferencePersistence; import cn.edu.zju.acm.onlinejudge.persistence.SubmissionPersistence; import cn.edu.zju.acm.onlinejudge.util.cache.Cache; public class ContestManager { private final Cache<List<Problem>> contestProblemsCache; private final Cache<AbstractContest> contestCache; private final Cache<Problem> problemCache; private final Cache<Submission> submissionCache; private final Cache<byte[]> descriptionCache; private final Cache<List<AbstractContest>> contestsCache; private final Cache<Integer> problemCountCache; /** * ContestManager. */ private static ContestManager instance = null; /** * <p> * Constructor of ContestManager class. * </p> * * @throws PersistenceCreationException * */ private ContestManager() throws PersistenceCreationException { this.contestProblemsCache = new Cache<List<Problem>>(60000, 50); this.contestCache = new Cache<AbstractContest>(60000, 30); this.problemCache = new Cache<Problem>(60000, 50); this.submissionCache = new Cache<Submission>(10000, 50); this.descriptionCache = new Cache<byte[]>(60000, 50); this.contestsCache = new Cache<List<AbstractContest>>(60000, 20); this.problemCountCache = new Cache<Integer>(60000, 20); } /** * Gets the singleton instance. * * @return the singleton instance. * @throws PersistenceCreationException */ public static ContestManager getInstance() throws PersistenceCreationException { if (ContestManager.instance == null) { synchronized (ContestManager.class) { if (ContestManager.instance == null) { ContestManager.instance = new ContestManager(); } } } return ContestManager.instance; } public List<AbstractContest> getAllContests() throws PersistenceException { return this.getContests(0); } public List<AbstractContest> getAllProblemsets() throws PersistenceException { return this.getContests(1); } public List<AbstractContest> getAllCourses() throws PersistenceException { return this.getContests(2); } public List<AbstractContest> getContests(int contestType) throws PersistenceException { Object key = new Integer(contestType); synchronized (this.contestsCache) { List<AbstractContest> contests = this.contestsCache.get(key); if (contests == null) { ContestPersistence contestPersistence = PersistenceManager.getInstance().getContestPersistence(); if (contestType==1) { contests = contestPersistence.getAllProblemsets(); } else if (contestType==0) { contests = contestPersistence.getAllContests(); } else { contests = contestPersistence.getAllCourses(); } this.contestsCache.put(key, contests); } return contests; } } public int getProblemsCount(long contestId) throws PersistenceException { Object key = new Long(contestId); synchronized (this.problemCountCache) { Integer count = this.problemCountCache.get(key); if (count == null) { ProblemPersistence problemPersistence = PersistenceManager.getInstance().getProblemPersistence(); int ret = problemPersistence.getProblemsCount(contestId); this.problemCountCache.put(key, ret); return ret; } return count.intValue(); } } public AbstractContest getContest(long contestId) throws PersistenceException { Object key = new Long(contestId); synchronized (this.contestCache) { AbstractContest contest = this.contestCache.get(key); if (contest == null) { ContestPersistence contestPersistence = PersistenceManager.getInstance().getContestPersistence(); contest = contestPersistence.getContest(contestId); this.contestCache.put(key, contest); } return contest; } } public List<Problem> getContestProblems(long contestId, int offset, int count) throws PersistenceException { ProblemCriteria criteria = new ProblemCriteria(); criteria.setContestId(new Long(contestId)); return this.searchProblems(criteria, offset, count); } public List<Problem> getContestProblems(long contestId) throws PersistenceException { ProblemCriteria criteria = new ProblemCriteria(); criteria.setContestId(new Long(contestId)); return this.searchProblems(criteria, 0, Integer.MAX_VALUE); } public List<Problem> searchProblems(ProblemCriteria criteria, int offset, int count) throws PersistenceException { List<Object> key = new ArrayList<Object>(); key.add(criteria); key.add(new Integer(offset)); key.add(new Integer(count)); synchronized (this.contestProblemsCache) { List<Problem> problems = this.contestProblemsCache.get(key); if (problems == null) { ProblemPersistence problemPersistence = PersistenceManager.getInstance().getProblemPersistence(); problems = problemPersistence.searchProblems(criteria, offset, count); this.contestProblemsCache.put(key, problems); } return problems; } } public Problem getProblem(long problemId) throws PersistenceException { Object key = new Long(problemId); synchronized (this.problemCache) { Problem problem = this.problemCache.get(key); if (problem == null) { ProblemPersistence problemPersistence = PersistenceManager.getInstance().getProblemPersistence(); problem = problemPersistence.getProblem(problemId); this.problemCache.put(key, problem); } return problem; } } public Submission getSubmission(long submissionId) throws PersistenceException { Object key = new Long(submissionId); synchronized (this.submissionCache) { Submission submission = this.submissionCache.get(key); if (submission == null) { SubmissionPersistence submissionPersistence = PersistenceManager.getInstance().getSubmissionPersistence(); submission = submissionPersistence.getSubmission(submissionId); this.submissionCache.put(key, submission); } return submission; } } public byte[] getDescription(long problemId) throws PersistenceException { Object key = new Long(problemId); synchronized (this.descriptionCache) { byte[] text = this.descriptionCache.get(key); if (text == null) { ReferencePersistence referencePersistence = PersistenceManager.getInstance().getReferencePersistence(); List<Reference> ref = referencePersistence.getProblemReferences(problemId, ReferenceType.DESCRIPTION); if (ref.size() > 0) { text = ref.get(0).getContent(); } else { text = new byte[0]; } this.descriptionCache.put(key, text); } return text; } } public void refreshContest(long contestId) { synchronized (this.contestProblemsCache) { for (Object key : this.contestProblemsCache.getKeys()) { ProblemCriteria criteria = ((List<ProblemCriteria>) key).iterator().next(); if (criteria.getContestId() == contestId) { this.contestProblemsCache.remove(key); } } } this.contestCache.remove(contestId); this.problemCountCache.remove(contestId); this.contestsCache.remove(true); this.contestsCache.remove(false); } public void refreshProblem(Problem problem) { this.refreshContest(problem.getContestId()); synchronized (this.problemCache) { this.problemCache.remove(new Long(problem.getId())); } synchronized (this.descriptionCache) { this.descriptionCache.remove(new Long(problem.getId())); } } }