首页 > 试题广场 >

系统设计题:设计一个服务调度管理器,服务器接收数据包,数据包

[问答题]
系统设计题:设计一个服务调度管理器,服务器接收数据包,数据包大小为32个字节,第一个字节是请求的优先级,后面31个字节是请求的命令,服务器根据客户端发来的命令,分配资源,完成相应的服务,然后将操作的结果返回给客户端,但是由于服务器资源有限,故服务器可以存储操作的结果,如果下次有同样的命令到来的时候,直接获取操作结果返回给客户端即可。
要求设计一个服务器调度管理器,满足以下调度条件:
(1)同样条件下,请求次数多的请求首先获得服务,请求次数最大255
(2)同样条件下,请求优先级高的请求首先获得服务,优先级等级最高16.
要做的是:
(1)设计服务器的核心调度算法:
(2)数据结构设计
(3)如果服务器的记录容量是20万条,分析需要占用多大内存空间??
#include <iostream>
#include <algorithm>
#include <hash_map>
//tdw
using namespace std;

struct SDataPackage//服务器接收的数据包
{
    char        priority;//优先级
    char        command[31];//请求命令
    SDataPackage()
    {
        priority = 0;//优先级0说明,该请求是空,不存在
        memset(command, 0, 31);
    }
    SDataPackage(const char req[32])
    {
        priority = req[0];
        memcpy(command,&req[0]+1,31);
    }
    bool operator ==(const SDataPackage& _other)
    {
        return (priority == _other.priority && memcmp(command,_other.command,31) == 0);
    }
};

struct SDataRequestList//跟某个请求排序有关的请求(前一个和下一个要处理的请求)
{
    int                        ncount;//请求次数
    SDataPackage            nextpackage;//比这个下一个处理的数据请求数据包
    SDataPackage            previouspackage;//比这一个前一个处理的数据
    SDataRequestList()
    {
        ncount = 0;
        nextpackage = SDataPackage();
        previouspackage = SDataPackage();
    }
};

hash_map<SDataPackage, void*> mapRequestResult;//已存在结果的请求
hash_map<SDataPackage, SDataRequestList> mapRequest;//还未处理的请求
SDataPackage firstDisposeRequest;//第一个需要处理的请求
SDataPackage lastDisposeRequest;//最后一个需要处理的请求
//以空间换时间是一种常用的手段,首先用"hash_map"把把数据接收的数据包存起来(如果已有操作结果,可直接返回结果)。
//同时构建相应的请求链,依据是请求次数多少,以及优先级。
void Request(const char req[32])//接收请求
{
    SDataPackage reqdata(req);
    hash_map<SDataPackage, void*>::iterator iter = mapRequestResult.find(reqdata);
    if (iter != mapRequestResult.end())
    {
        //iter->second;已找到操作结果
        return;
    }

    if (firstDisposeRequest.priority == 0 && lastDisposeRequest.priority == 0)//第一个没有应答的请求
    {
        firstDisposeRequest = reqdata;
        lastDisposeRequest = reqdata;
        SDataRequestList reqlist;
        reqlist.ncount = 1;
        mapRequest.insert(make_pair(reqdata, reqlist));
        return;
    }

    hash_map<SDataPackage, SDataRequestList>::iterator iterreq = mapRequest.find(reqdata);//找到这个请求
    if (iterreq != mapRequest.end())
    {
        ++iterreq->second.ncount;
        if (reqdata == firstDisposeRequest)
            return;//第一个,没有需要查找的前一个需要处理的
        if (reqdata == lastDisposeRequest)
        {//需要特殊处理一下,当前请求在末尾
            if (iterreq->second.previouspackage.priority > 0)//前一个不为空
            {
                hash_map<SDataPackage, SDataRequestList>::iterator iterpre = mapRequest.find(iterreq->second.previouspackage);//前一个的请求前后关联的信息
                if (iterpre != mapRequest.end())//如果找不到。说明存在异常
                {
                    if (iterpre->second.ncount >= iterreq->second.ncount)
                    {//该请求还是在最后一个,不影响处理请求的排序
                        return;
                    }
                    else
                    {
                        iterpre->second.nextpackage = iterreq->second.nextpackage;
                        iterreq->second.previouspackage = iterpre->second.previouspackage;
                        iterpre->second.previouspackage = reqdata;
                        lastDisposeRequest = iterpre->first;//最后一个处理请求变更
                    }
                }
            }
        }

        while (true)
        {
            SDataPackage pre = iterreq->second.previouspackage;//该请求的前一个请求
            SDataPackage next = iterreq->second.nextpackage;//该请求的下一个请求
            hash_map<SDataPackage, SDataRequestList>::iterator iterpre = mapRequest.find(pre);
            if (iterpre != mapRequest.end())
            {
                if (iterpre->second.ncount >= iterreq->second.ncount)
                {//找到了该请求处理的位置,不需要变更位置
                    break;
                }
                else
                {//交换一下,当前请求和前一个需要处理的请求的位置
                    
                    hash_map<SDataPackage, SDataRequestList>::iterator iternext = mapRequest.find(next);
                    if (iternext != mapRequest.end())//如果找不到,不用再考虑
                        iternext->second.previouspackage = iterpre->first;
                    iterpre->second.nextpackage = iterreq->second.nextpackage;
                    iterreq->second.previouspackage = iterpre->second.previouspackage;
                    iterpre->second.previouspackage = reqdata;
                }
            }
            else
            {//如果找不到。说明这个请求已经排在了第一个位置
                firstDisposeRequest = iterreq->first;
                break;
            }
        }
    }
    else
    {//没有找到该请求,所以添加到末尾,最后一个请求变更
        SDataRequestList reqlist;
        reqlist.ncount = 1;
        reqlist.previouspackage = lastDisposeRequest;
        lastDisposeRequest = reqdata;
        mapRequest.insert(make_pair(reqdata, reqlist));
        return;
    }
}
void Dispose()//处理请求
{
    if (firstDisposeRequest.priority == 0 && lastDisposeRequest.priority == 0)
        return;//没有需要处理的请求

    hash_map<SDataPackage, SDataRequestList>::iterator iterfirst = mapRequest.find(firstDisposeRequest);
    if (iterfirst != mapRequest.end())//一定能找到
    {
        hash_map<SDataPackage, SDataRequestList>::iterator iternext = mapRequest.find(iterfirst->second.nextpackage);
        if (iternext != mapRequest.end())
        {
            iternext->second.previouspackage = SDataPackage();//下一个请求的,前一个请求为空
        }
        else
        {
            lastDisposeRequest = SDataPackage();//最后一个需要处理的请求
        }
        firstDisposeRequest = iterfirst->second.nextpackage;
    }
}

发表于 2018-05-28 17:04:59 回复(0)