这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/SE2020 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/SE2020/homework/11167 |
这个作业的目标 | 实现一个 Github 用户行为数据统计器;初步掌握文档编写、单元测试与性能优化技术 |
学号 | 031802422 |
TODO
Github 与 VS 配置- 代码规范制定 codestyle.md
- PSP 表格
需求分析模块设计- 学习:单元测试
- 学习:性能分析
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 120 |
Estimate | 估计这个任务需要多少时间 | 60 | 120 |
Development | 开发 | ||
Analysis | 需求分析 (包括学习新技术) | 480 | 360 |
Design Spec | 生成设计文档 | 120 | 150 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | ||
Design | 具体设计 | 120 | 150 |
Coding | 具体编码 | ||
Code Review | 代码复审 | ||
Test | 测试(自我测试,修改代码,提交修改) | ||
Reporting | 报告 | ||
Test Report | 测试报告 | ||
Size Measurement | 计算工作量 | ||
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | ||
合计 |
需求分析
- 命令行参数解析
- json 解析
- 大数据检索
- 有限的内存
- 统计特定记录的数量
- 目录读取
功能设计
- 参数解析
- json 解析
- 性能优化
- 预处理
- 仅提取
type, actor.login, repo.name
- 逐行读取
- 直接进行统计,结果存盘c
- 用
unordered_map
实现 hashmap - 仅 user 或仅 repo : hashmap 映射到次数记录之
- user & repo : 二者合并后 hashmap 之
- 存盘
- 问题:Cpp 下序列化实现不便
- 方案:手工遍历,转 JSON 后写文件
- 用
- 仅提取
- 预处理
- 查询
- 直接全文件 parse 后在 CJsonObject 上查询
- 目录读取
- Windows 下采用 io.h
- Linux 下采用 dirent.h
模块设计
- GHAnalysis.cpp
main(argc, argv)
- 初始化
- 参数解析器
- 有效事件表
- 根据参数选择功能
- 存在
--init
:取路径调用analyze()
- 否则:
- 取出各字段初始化
fieldList
和event
- 调用
lookup()
- 打印结果
- 取出各字段初始化
- 存在
- 初始化
analyze(path)
- 实现预处理
- 流程
- 建文件表,Mapper 表
- 遍历文件表
- 按行读取
- 解析为
CJsonObject
对象 EventCount::isValid(getEvent())
?- 遍历 Mapper 表,逐个更新
- 遍历 Mapper 表,逐个
toJSON()
存入<getFields().getName()>.json
lookup(fields)
- 打开并解析
<fields.getName()>.json
- 返回以
fields.value()
为 key 的CJsonObject
对象
- 打开并解析
- FileIO.cpp
FileList
openAll(dirPath, endWith)
size()
begin()
end()
closeAll()
- Mapper.cpp
Mapper
fields {get; set;}
toJSON(&cJsonObj)
unordered_map<string, EventCount> hashmap
update(&cJsonObj)
- 获取各字段值
- 根据字段值查找
EventCount
并更新
- Field.cpp
Field
value {get; set;}
virtual getName()
virtual setValueFromJSON(&cJsonObj)
virtual addToCmdParser(parser)
FieldUser : Field
FieldRepo : Field
FieldList
add(*Field)
getName()
- 返回所有
Field.getName()
的拼接,用"-"
分隔
- 返回所有
value()
- 返回所有
Field.getValue()
的拼接,用"-"
分隔
- 返回所有
setValueFromJSON(&cJsonObj)
- Event.cpp
getEvent(&cJsonObj)
EventCount
static validEvents[]
static addEvent(str)
static isValid(str)
update(&cJsonObj)
toJSON(&cJsonObj)