Repository: ossrs/srs
File: trunk/src/app/srs_app_http_stream.cpp (C++)

Code before:
    SrsStatistic* stat = SrsStatistic::instance();
    if ((err = stat->on_client(_srs_context->get_id().c_str(), req, hc, SrsFlvPlay)) != srs_success) {
        return srs_error_wrap(err, "stat on client");
    }

    if ((err = security_->check(SrsFlvPlay, req->ip, req)) != srs_success) {
        return srs_error_wrap(err, "flv: security check");
    }

    // We must do hook after stat, because depends on it.
    if ((err = http_hooks_on_play(r)) != srs_success) {
        return srs_error_wrap(err, "http hook");
    }

    // Add the viewer to the viewers list.
    viewers_.push_back(hc);

    // Serve the viewer connection.
    err = do_serve_http(w, r);

    // Remove viewer from the viewers list.
    vector<ISrsExpire*>::iterator it = std::find(viewers_.begin(), viewers_.end(), hc);
    srs_assert (it != viewers_.end());
    viewers_.erase(it);

    // Do hook after serving.
    http_hooks_on_stop(r);
    
    return err;
}

bool SrsLiveStream::alive()
{
    return !viewers_.empty();
}

void SrsLiveStream::expire()
{
    vector<ISrsExpire*>::iterator it;
    for (it = viewers_.begin(); it != viewers_.end(); ++it) {
        ISrsExpire* conn = *it;
        conn->expire();
    }
}

srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
    srs_error_t err = srs_success;
    
    string enc_desc;
    ISrsBufferEncoder* enc_raw = NULL;

Review comment (suggestion):
`viewers_`, as `vector` container , has bad efficiency in `erase`,  and also `find` for unsorted data.
For one SRS instance, it is reasonable to support 1K flv http connection. 
So it's 1K unsorted vector search and delete frequently. (Not so bad, also not so good).
If the vector size is 10K, it will be serious problem.
 
 In those reason, consider `map` or `unordered_map` as the container. the `SrsHttpConn->get_id` as the key, make sure the key is unique for each `SrsHttpConn`.

Code after:

    // We must do stat the client before hooks, because hooks depends on it.
    SrsStatistic* stat = SrsStatistic::instance();
    if ((err = stat->on_client(_srs_context->get_id().c_str(), req, hc, SrsFlvPlay)) != srs_success) {
        return srs_error_wrap(err, "stat on client");
    }

    if ((err = security_->check(SrsFlvPlay, req->ip, req)) != srs_success) {
        return srs_error_wrap(err, "flv: security check");
    }

    // We must do hook after stat, because depends on it.
    if ((err = http_hooks_on_play(r)) != srs_success) {
        return srs_error_wrap(err, "http hook");
    }

    // Add the viewer to the viewers list.
    viewers_.push_back(hc);

    // Serve the viewer connection.
    err = do_serve_http(w, r);

    // Remove viewer from the viewers list.
    vector<ISrsExpire*>::iterator it = std::find(viewers_.begin(), viewers_.end(), hc);
    srs_assert (it != viewers_.end());
    viewers_.erase(it);

    // Do hook after serving.
    http_hooks_on_stop(r);
    
    return err;
}

bool SrsLiveStream::alive()
{
    return !viewers_.empty();
}

void SrsLiveStream::expire()
{
    vector<ISrsExpire*>::iterator it;
    for (it = viewers_.begin(); it != viewers_.end(); ++it) {
        ISrsExpire* conn = *it;
        conn->expire();
    }
}

srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
    srs_error_t err = srs_success;