MYSEE:Sp数据结构分析初稿
以前写了MYSEE 服务器端源码分析文档,主要是对其中的消息机制(sp,cp,ts,之间的交互)的分析。因为CU抽风,发表的文章无故给我删除了 ,所以这个不是完整的
Sp 数据结构分析(初稿)
一:准备工作
1 )熟悉 /opt/mysee/data/sp/ 目录下面有哪些目录( channel data playlist program )
2 )在目录 program 中有三个文件( 0 config keysample )
3 )知道一个 channel 到底是什么,里面包含什么东西?
这个问题困扰了我很久。
我现在的理解是这样的,在 program 中包含有很多目录,比如 /opt/mysee/data/sp/program/29bea7e94db8359982f1976e40cd780b , 都是 32 位的 16 进制数。 里面包含了 3 个文件( 0 config keysample )。 这个里面的文件是管理员上传的。在 sp 目录下面还有一个目录 channel 。说到这里,我说说一部电影是怎么传上去的(举例) 首先用格式转换工具将 .avi 等视频文件转换成为一个目录文件 29bea7e94db8359982f1976e40cd780b ,里面当然包含三个文件( 0 config keysample ) ,管理员将这个目录上传到 /opt/mysee/data/sp/program 中,这个是第一步。在系统初始化的时候,系统会打开 program 目录,然后依次检查下面的文件(比如 29bea7e94db8359982f1976e40cd780b )是否在 programhash 列表中,如果不在其中,我们就调用 callo 函数生成一个 channel 数据结构,赋值(没有对 channel 结构中的 media 指针赋值),然后添加到 programhash 列表。再对 channel 中的 media 指针赋值,添加到 channelhash 当中。
说说 media 是怎么赋值的,这个指针是指向 config 文件里面的一个数据字段 data 的
Config 文件内容如下:
BitRate=34.705500
BlockSize=16384
ChannelName=[2008.08.03] 军鸡 +shamo.2007
ResourceHash=29bea7e94db8359982f1976e40cd780b
DataLength=220
Data =vids^@^@^P^@<80>^@^@ª^@8<9b>qVP70^@^@^P^@<80>^@^@ª^@8<9b>q<80><9f>X^EVÃÃ^A^@ª^@UYZ^A^@^@^@Â^B^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@;]^F^@^@^@^@^@(^@^@^@^@^B^@^@<80>^A^@^@^A^@^L^@VP70^@^P^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@auds^@^@^P^@<80>^@^@ª^@8<9b>q1^@^@^@^@^@^P^<80>^@^@ª^@8<9b>q<81><9f>X^EVÃÎ^Q¿^A^@ª^@UYZA^@^@^@¡^@^@^@1^@^A^@D¬^@^@ý^@^@^B^@@^A
Programhash 和 channelhash 有什么区别? 为什么要分成两个 hash ,这两 hash 表又是怎么联系起来的?
用 hash 肯定是为了提高查询效率,我理解是在 channel 结构体中有一个 int ref 成员,它是一个 channel 的引用数, 当引用数 ref < 0 时,我们将改它从 programhash 表里面删除。
两个表的区别:
/opt/mysee/data/sp/program 目录中的文件是一直存在的,
/opt/mysee/data/sp/channel 目录中的文件是在打开节目是时候生成的,并且在改节目关闭后一定时间内是会删除的,这个在代码中是可以看见的。
上面这些我觉得就是要拥有两个 hash 表的原因,至于两者是怎么联系的。 (比如当在 channelhash 中删除一个 channel 时,对 programhash 中的相应的 channel 的应用数( ref )要减一)这个在下面具体数据结构中再分析
说了这么多废话其实是为了更好的理解下面的数据结构中成员的意思 :-D
二:具体数据结构分析
struct LiveChannelInfo
{
unsigned int maxID; // 这个 channel 全部文件中最大的 id 可以通过 newPListChannelFile 这个函数看出来
struct Session *dataSource; // source of data, a connection to SP or uplevel CP
unsigned int total;
struct SPUpdate s;
unsigned int max_queue; //pcinfo->max_queue = BLOCK_PER_FILE; 这个应该是每个文件所拥有的最大块的数目,要注意它和每一块多大的区别
float bitrate; // 码率
// struct BlockData *blocks;
int max_channel; // 有多少个频道
int cur_channel; // 当前 channel 数目
struct MediaData *media;
int isSave;//guess : issave = 1 represent save the channel (这个是在关闭 channel 的时候用的)
#ifdef __CP_SOURCE
char *bitflag; // for CP, it is pending status, for SP, it is keysample status
unsigned char *indisk;
unsigned int numofsp;
struct NormalAddress SPLIST[256];
#endif
#ifdef __SP_SOURCE
unsigned int startid;
struct MList *mlist; // 指向频道链表
/*
for the dir of /data/sp/program/ , there are three files . now we watch out the file 0,
input pointer point to this file . they may have more than just one file . but not beyond the numb of MAX_FILEINPUT .
in this project , we reality it just have only one file "0"
*/
FILE *input [MAX_FILEINPUT]; // 一个 channel 拥有的文件名列表
FILE *keyfile;// 这个指向我们每一个文件下面的那个 keysample 文件
unsigned int numinput; //the number of files one channel contains
unsigned int numblocks;
unsigned int userid;
float limitedBitRate;
unsigned int status; // 1 meaning this channel has been closed
time_t updated; // channel update time
#endif
};
注意:在这个数据结构中没有对 media 这个指针的操作
Input 指针也是重点要注意的
首先要注意的是 input 和 m_lists 的指针类型,一个是 file * , 一个是 channel *
两者都相当于二重指针, input 指向( 0 config keysample ) 0 这个文件 ,这里说说代码中为什么要用二重指针,这里只有一个文件( 0 这个文件),用一重的也可以呀! 代码实现中规定一个 channel 里面最多可以有 max_fileinput 这么多个文件,但是在我们的具体实现中只是生成了一个 文件 0 (你喜欢也可多生成一些,比如 1 , 2 文件等)。 这里的指针 m_lists 就是连接 channelhash 和 programhash 的指针。
----------------------------------------------------------------------------------------------------------------------
struct Channel
{
int type;
int ref ; // 某个节目的引用数 ( 也可以说频道的引用数 )
char fname[CHNLURL_LEN]; //filename 这个是通过 buildProgPath 这个函数生成的
char channel_name[CHNLURL_LEN];// 频道名
char channel_md5[MD5_LEN+1]; // 频道名 md5 码
int maxblocksize;// 从 config 文件中读取的 blocksize 大小 ( 每块的大小 ), 注意与 datalenght 的区别
int numclient; //
int numjob; // number of jobs
unsigned int ctime;
#ifdef __SP_SOURCE
int numofnp[MAX_TS];
#endif
#ifdef __CP_SOURCE
time_t last_nearpeer;
#endif
long long downsize; // recv from SP for CP, file size for SP;
long long upsize; // send to NP
FILE *db;
struct LiveChannelInfo *pcinfo;
struct Edge *PeerHead; //channel list head
struct Channel *next;// 具有相同 id 的 channel 的链接
struct Channel *lnext; // 全部 channel 的链接
};
注意:最后三个指针
struct Session
{
int type;
int socket;// 由 handle_new_connection 这个函数赋值
#ifdef __CP_SOURCE
unsigned char npcp; //TYPE_CP
unsigned char flag;
unsigned short first;
unsigned int sock_flag; /* saved for restore after connection succed */
float version; //np 的版本号,这个是从 message 的开头 的内存中读取出来的。
long long totalup;
struct PeerInfoWithAddr addr;
// struct CorePeerInfo *c;
// struct TransferInfo *t;
#endif
/*
at first ,we know that session present a client connect to sp .so the host and port is the value of the client (cp)
watch out the type of this two value
*/
unsigned int host;
unsigned int port;
unsigned int time_sec; //time of creation
unsigned int last_transferblock; //time of last send or recv a block
// 这里就很清楚了, off 其实就是 message 的长度
// buf+start 是 message 指针指向的地方
char *buf;
unsigned int start;
unsigned int off;
unsigned int numjob;
struct JobDes *head;
struct Channel *pc;// difficult point ( 在一个 session 中包含这个元素有什么作用 ?
struct Edge *header;
// 每个 session 通过 Edge 中的 enext 也串成一个链表。
// 这个链表的头是 session 结构中的 header 指针
struct Session *next;
};
struct Edge
{
struct Channel *head;
struct Session *me;
struct Edge *cnext;
struct Edge *enext;
};
最后说说 edge
Session: D,E
Channel A,B,C
Edge : P 等
对于 edge p ,对应 channel A 和 Session D 。举例分析
当我们要删除边 p 的时候
对与 channelA ,通过单向链表表头 PeerHead 来寻找所有连接到 A 上面的 edge ,如果表头第一个指向的边不是 p ,通过第一条边的 cnext 指针寻找下一条边。 直到找到或为 null 为止,然后删除改边
对于 Session D,通过单向链表表头 header 来寻找所以连接到改 Session 的所以边,如果表头第一个指向的边不是 p ,通过第一条边的 enext 指针寻找下一条边。 直到找到或为 null 为止然后删除改边
这是只是我的笔记,欢迎讨论 ^_^
MYSEE:Sp数据结构分析初稿相关推荐
- 数据结构分析:红黑树、B+树
数据结构分析:红黑树.B+树 前言 常见的数据结构大概分为以下8种,作为一个开发人员,数据结构是内功之一. 本文参考了网络上相关知识,加之自己的理解.简单说明红黑树.B+树的特性. 1. 二叉搜索树( ...
- 【Android 逆向】函数拦截 ( GOT 表数据结构分析 | 函数根据 GOT 表进行跳转的流程 )
文章目录 一.GOT 表数据结构分析 二.函数根据 GOT 表进行跳转的流程 一.GOT 表数据结构分析 GOT 表分为 222 部分 , 一部分在 调用者部分 ( 可执行文件 ) 中 , 一部分在 ...
- ffplay的数据结构分析
<ffplay分析(从启动到读取线程的操作)> <ffplay分析(视频解码线程的操作)> <ffplay分析(音频解码线程的操作)> <ffplay 分析( ...
- 硬盘扇区数据结构分析
来自 http://hi.baidu.com/qtycr/blog/item/f6cc9b2b74e2d7fee7cd40da.html 硬盘扇区数据结构分析 初买来一块硬盘,我们是没有办法使用的,你 ...
- 音视频从入门到精通——FFmpeg数据结构分析
FFmpeg数据结构分析 FFmpeg解码流程 重要结构体之间的关系 AVFormatContext iformat:输入媒体的AVInputFormat,比如指向AVInputFormat ff_f ...
- 商品分类目录数据结构分析
商品分类目录数据结构分析 说明:一般电商网站的商品分类信息,都是3级标题. 划分: 1级标题-2级标题-3级标题 标题是有所属关系的 /1.查询一级商品分类信息/ SELECT * FROM tb_i ...
- SICK LMS511开发及数据结构分析、坐标转换
SICK LMS511开发及数据结构分析.坐标转换 最近公司有新上的项目,开始接触激光扫描仪,型号SICK LMS511. 获取数据 在网上看了一些资料,有通过SICK自带的软件看了一下激光扫描仪的配 ...
- 【JAVA进阶】java中的集合(番外篇3)- HashMap源码底层数据结构分析
写在前面的话 脑子是个好东西,可惜的是一直没有搞懂脑子的内存删除机制是什么,所以啊,入行多年,零零散散的文章看了无数,却总是学习了很多也忘了很多. 痛定思痛的我决定从今天开始系统的梳理下知识架构,记录 ...
- 【Apache OFBiz 系列】OFBiz的数据结构分析(五)
前面一系列的数据结构分析分别整理了ofbiz的通用模块.网站信息模块.内容模块.调查问卷模块,但是一直未呈现信息化中的主体--人员,这篇文章全面整理了ofbiz的会员管理模块数据模型,ofbiz对会员 ...
最新文章
- javascript 判断字符串中是否包含某个字符串
- SAP IDoc Post不成功,报错 - Conventional invoice verification no longer maintained as of Release 4.6-
- Vmware vSphere 5.0安装和配置
- 2019年第十届蓝桥杯 - 省赛 - C/C++研究生组 - G. 扫地机器人
- 设置activity不可返回
- linux pidof用法,科技常识:Linux pidof命令使用总结
- 网络设计分层设计的原理
- Microsoft Updater Application Block 1.4.3 KeyValidator类设计 [翻译]
- Android之PreferenceActivity (转载)
- 阶段3 2.Spring_02.程序间耦合_8 工厂模式解耦的升级版
- JavaWeb后端开发框架SSM+前端框架Layui简介
- 他因“上帝粒子”获诺奖,却火速搬到乡下:它毁了我的生活
- Fxfactory插件:电影调色插件PHYX Color
- 为什么未来是全栈工程师的世界?
- 大地坐标系、地理坐标系、投影坐标系
- 手把手教你接入微信开放平台,实现网站拉起微信账号登录,从0开始详细记录
- PhxRPC源码简析
- git时光穿梭机---女神的侧颜
- 运用docker部署nessus+awvs
- git已经设置了name和email但是还是提示please tell who you are
热门文章
- Ubuntu ssh连接access deny
- CF662C Binary Table FWT
- 职业教育/培训研究报告(精选七篇)
- Android疯狂ListViw之旅 第二季之 分组排序显示数据
- 产品 电信nb接口调用_基于NB-IoT平台数据透传模式的应用接入平台设计方法与流程...
- 虚拟机不能识别本地镜像
- 带以太网和 CAN 的低压模块-德国KLARIC 新款KLARI-FUSE3|新能源静态电压电流数据采集模块
- matplotlib绘图
- java 盲水印_GitHub - Yxiaojian/BlindWaterMark: Java盲水印
- mac安静执行脚本_让Mac OS X系统启动时执行脚本的方法