一.目的
负责负载均衡,获取网站首页,通过网络罗调用编译并运行并提供结果给用户。根据用户的操作提供不同的功能。采用mvc结构。使用 ctemplate文字模板做数据渲染
m在这里指的是和数据的交互,可以用文件或者sql交互。在使用文件的情况下,就必须要有对应的文件目录存放每一道题。提供题目描述和题头还有测试用例。
二.实现model
负责将文件题库抽象成数据结构,并提供接口给ojcontrol调用。ojcontrol通过model模块获取全部的题目信息和测试用例,用来交给后端服务继续运行
题的数据结构
typedef struct Question // 每一道题对应的基本信息
{
string number; // 题目编号
string title; // 题目名称
string diffculty; // 题目难度
int cpu_limit; // 运行时间限制
int mem_limit; // 内存时间限制
string desc; // 题目描述
string header; // 题目提供给用户的首部代码
string tailer; // 题目的测试用例,需要和header拼接,形成完整代码
}Question;
获取题信息的数据结构,因为是从文件中读取,所以需要一个字符串格分割函数。
加载所有题库信息到数据结构。
bool LoadQuestionList(const string question_path) //根据文件题目列表获取到数据结构内
{
ifstream in(questionlist_path); // 打开题目列表的文件流
if (!in.is_open()) // 打开文件流失败
{
LOG(FATAL) << "加载题库失败,请检查是否存在题库文件"
<< "\n";
return false;
}
string line;
while (getline(in, line))
{
vector<string> tokens; // 题的五个信息
StringUtil::SplitString(line, &tokens, " "); // 根据空格分隔出不同元素
if (tokens.size() != 5) // 每道题有五种基本信息(编号,题目,,难度,mem,cpu)
{
LOG(WARNING) << "加载部分题目失败, 请检查文件格式"
<< "\n";
continue; // 获取当前题目信息失败直接跳过
}
Question q; // 创建题目对象填充信息
q.number = tokens[0];
q.title = tokens[1];
q.diffculty = tokens[2];
q.cpu_limit = atoi(tokens[3].c_str());
q.mem_limit = atoi(tokens[4].c_str());
// 获取题目详细信息
string path = question_path; // 需要拼出对应的题目路径
path += q.number;
path += "/";
// 从文件内读出内容并填充进题目结构体里
FileUtil::ReadFile(path + "desc.txt", &(q.desc), true);
FileUtil::ReadFile(path + "header.cpp", &(q.header), true);
FileUtil::ReadFile(path + "tail.cpp", &(q.tailer), true);
// 形成哈希映射
questions.insert({q.number, q});
}
LOG(INFO) << "题库加载成功"
<< "\n";
in.close();
return true;
}
获取一道题给客户
bool GetOneQuestion(const string &number, Question *ret) // 通过题号获取对应题
{
const auto &iter = questions.find(number);
if (iter == questions.end())
{
LOG(ERROR) << "用户获取题目失败, 题目编号: " << number << "\n";
return false;