2022-09-15

include

include

include

include

include

include

include

using namespace std;
using namespace chrono;

struct Courier {
int64_t arriveTime;
bool operator < (const Courier &co) const {
return arriveTime < co.arriveTime;
}
bool operator > (const Courier &co) const {
return arriveTime > co.arriveTime;
}
};

struct Order{
string id;
string name;
int prepareTime; // second
int64_t dispatchTime;
int64_t finishTime; // finish finishTime

Order() {
    prepareTime = 0;
    finishTime = 0;
    id = "";
    name = "";
}
Order(Order *order) {
    this->id = order->id;
    this->name = order->name;
    this->prepareTime = order->prepareTime;
    this->finishTime = order->finishTime;
}
bool operator < (const Order &od) const
{
    return finishTime < od.finishTime; 
}
bool operator > (const Order &od) const
{
    return finishTime > od.finishTime;
}

};

template
class MyQueue {
public:
virtual int Init(int cap) = 0;
virtual void Deinit() = 0;
virtual int Push(NODE order) = 0;
virtual NODE GetFrontAndPop(void) = 0;
virtual bool IsFull(void) = 0;
virtual bool IsEmpty(void) = 0;
};
template
class Queue : public MyQueue {
public:
Queue() {
this->capicity = INT_MAX;
}
int Init(int cap)
{
this->capicity = cap;
pthread_mutex_init(&(this->mutex), NULL);
}
void Deinit()
{
// lock , free order
pthread_mutex_lock(&(this->mutex));
while (!this->que.empty()) {
this->que.pop();
}

    pthread_mutex_unlock(&(this->mutex));

    //
    pthread_mutex_destroy(&(this->mutex));
    return;
}

int Push(NODE order)
{
    //cout<<"input order id: "<que.size() >= this->capicity) {
        return -1;
    }
    this->que.push(order);
    return 0;
}
bool IsFull() {
    return this->que.size() == this->capicity;
}
bool IsEmpty() {
    return this->que.empty();
}
NODE GetFrontAndPop() {
    while (this->que.empty()) {
        // error
        std::this_thread::sleep_for(1000ms);
        cout<<"que is empty\n";
    }
    NODE order = this->que.front();
    this->que.pop();
    return order;
}

private:
int capicity;
queue que;
pthread_mutex_t mutex;
};
template
class ProQueue : public MyQueue {
public:
ProQueue() {
this->capicity = INT_MAX;
}
int Init(int cap)
{
this->capicity = cap;
pthread_mutex_init(&(this->mutex), NULL);
}
void Deinit()
{
// lock , free order
pthread_mutex_lock(&(this->mutex));
while (!this->que.empty()) {
this->que.pop();
}

    pthread_mutex_unlock(&(this->mutex));

    //
    pthread_mutex_destroy(&(this->mutex));
    return;
}

int Push(NODE order)
{
    if (this->que.size() >= this->capicity) {
        return -1;
    }
    this->que.push(order);
    return 0;
}
bool IsFull() {
    return this->que.size() == this->capicity;
}
bool IsEmpty() {
    return this->que.empty();
}
NODE GetFrontAndPop() {
    while (this->que.empty()) {
        // error
        std::this_thread::sleep_for(1000ms);
        cout<<"que is empty\n";
    }
    NODE order = this->que.top();
    this->que.pop();
    return order;
}

private:
int capicity;
priority_queue, greater> que;
pthread_mutex_t mutex;
};

class Input {
public:
int Product(MyQueue *myque, void *args)
{
Order order = (Order)args;
Order od(order);
int ret = myque->Push(order);
return ret;
}
};

//typedef (int*)Rand(int min, int max);

class Dispatch {
public:
virtual int DispatchOrder(MyQueue *que, MyQueue *couriers) = 0;
int RegistRand();
int CariesArrivedTime(int min, int max)
{
// rand from min to max, [min, max]
return 0;

}
void AddFoodWait(int prepareTime)
{
    this->foodwait += prepareTime;
}
int64_t GetFoodWait()
{
    return foodwait;
}
void AddCariesWait(int wait)
{
    this->carieswait += wait;
}
int64_t GetCariesWait()
{
    return carieswait;
}
void AddOrders() {
    orders++;
}
int64_t GetOrders() {
    return orders;
}
int64_t GetAvgFoodWaitTime() {
    if (orders == 0) {
        return 0;
    }
    return foodwait / orders;
}
int64_t GetAvgCariesWaitTime() {
    if (orders == 0) {
        return 0;
    }
    return carieswait / orders;
}

private:
int64_t foodwait;
int64_t carieswait;
int64_t orders;
};

class Matched : public Dispatch
{
public:
int DispatchOrder(MyQueue *que, MyQueue *couriers)
{
Queue *q = (Queue *)que;
Queue *cou = (Queue *)couriers;
if (cou->IsEmpty()) {
cout<<"couries is empty!\n";
return -3;
}
Order order = q->GetFrontAndPop();
Courier courier = cou->GetFrontAndPop();
if (order.finishTime >= courier.arriveTime) {
AddCariesWait(order.finishTime - courier.arriveTime);
} else {
AddFoodWait(courier.arriveTime - order.finishTime);
}
AddOrders();

    cout<<"Match Dispatch "<

};

class FIFO : public Dispatch
{
public:
int DispatchOrder(MyQueue *que, MyQueue *couriers)
{
ProQueue q = (ProQueue)que;
Order order = q->GetFrontAndPop();
auto now = duration_cast(system_clock::now().time_since_epoch()).count();
if (now < order.finishTime) {
q->Push(order);
return -2;
}
cout<<"Match Dispatch "< return 0;
}

};

class Notify {
public:
int FilePath(const char *path) {

}
void Print(string s) {
    cout<

};

enum STRATEGIE {
STRATEGIE_MATCH = 0x01, // match strategie
STRATEGIE_FIFO // fifo strategie
};

struct Config {
STRATEGIE st;
int32_t cap;
};

class Server{
private:
std::condition_variable full;
std::condition_variable emp;
std::mutex mtx; // 保护队列
int64_t capicity;
int64_t nums; // 队列中的数量
int64_t emptys; // 空闲数量
int stragegie; // 策略
Dispatch *dispatch;
MyQueue *que;
MyQueue *couriers;
Notify notify;

public:
int InitServer(Config *conf);
void DeInitServer();

int ReadData(const char* file);

int DispatchOrder();
int Statistics();

};

int Server::InitServer(Config *conf)
{
// default conf
if (conf == NULL) {
stragegie = STRATEGIE_MATCH;
capicity = 10;
} else {
stragegie = conf->st;
capicity = conf->cap;
}

if (stragegie == STRATEGIE_MATCH) {
    Matched *match = new Matched();
    dispatch = (Dispatch*)match;
    Queue *que = new Queue();
    que->Init(capicity);
    this->que = (Queue*)que;
    this->couriers = new Queue();
} else if (stragegie == STRATEGIE_FIFO) {
    FIFO *fifo = new FIFO();
    dispatch = (Dispatch*)fifo;
    ProQueue *que = new ProQueue();
    que->Init(capicity);
    this->que = (ProQueue*)que;
    this->couriers = new ProQueue();
}
return 0;

}

int Server::ReadData(const char* file)
{
auto start = system_clock::now();
auto end = system_clock::now();

// fen duan duqu?
static int times = 0;
while (true) {
    std::this_thread::sleep_for(2000ms);
    std::unique_lock lock(mtx);

    this->emp.wait(lock, [this]{return !que->IsFull();});

    static int64_t id = 0;
    for (int i = 0; i < 2; i++) {
        Order order;
        order.name = "rndNO" + to_string(id) + "*";
        order.id = to_string(id);
        id++;
        order.prepareTime = rand() % 15000; // 0-15s
        order.dispatchTime = duration_cast(system_clock::now().time_since_epoch()).count();
        order.finishTime = order.dispatchTime + order.prepareTime;
        que->Push(order);
        Courier courier;
        courier.arriveTime = order.dispatchTime + rand() % 15000;
        if(couriers->Push(courier) != 0) {
            cout<<"couriers push error\n";
        }
        notify.Print("push " + order.name + " " + to_string(order.finishTime));
    }
    times++;
    if (times >= 10) {
        int64_t fw = dispatch->GetAvgFoodWaitTime();
        int64_t cw = dispatch->GetAvgCariesWaitTime();
        notify.Print("food wait time: " + to_string(fw) + "ms couries wait time: " + to_string(cw));
        return 0;
    }
    emp.notify_all();
}

}

int Server::DispatchOrder()
{
while (true) {
std::this_thread::sleep_for(100ms);
std::unique_lock lock(mtx);
this->emp.wait(lock, [this]{return !que->IsEmpty();});
if (dispatch->DispatchOrder(que, couriers) == -2) { // order not prepared, couries not arrived

    }
    emp.notify_all();
    
}

}

int ProductOrder(Server* server, const char* file)
{
return server->ReadData(file);
}

int DispatchOrder(Server* server)
{
return server->DispatchOrder();
}

int main()
{
/* Queue myque;
myque.Init(10);
Input input;
//myque.Init(100);
Matched match;

thread read(Read, "/home/err", &myque);
thread disp(DispatchMeth, &myque, &match);
read.join();
disp.join(); */

Server server;
server.InitServer(NULL);

thread read(ProductOrder, &server, "/home/err");

thread disp(DispatchOrder, &server);
//thread disp1(DispatchOrder, &server);
read.join();

disp.join();
//disp1.join();


cout<<"hello world\n";

}

你可能感兴趣的:(2022-09-15)