Пример #1
0
/* push index */
int qindex_push_index(QINDEX *qindex, int64_t key, IBDATA *block)
{
    DOCHEADER *docheader = NULL;
    XPACKET *xpackets = NULL;
    int mid = 0, old = 0;

    if(qindex && block->ndata > 0 && (docheader = (DOCHEADER *)block->data)) 
    {
        MUTEX_LOCK(qindex->mutex);
        if(docheader->size == block->ndata && (xpackets = (XPACKET *)(qindex->xpacketio.map))
            && (mid = mmtree64_try_insert(qindex->idmap, qindex->state->rootid, 
                            key, (qindex->state->id_max+1), &old)) > 0)
        {
            if(old > 0) mid = old;
            else mid = ++(qindex->state->id_max);
            db_set_data(PDB(qindex->db), mid, block->data, block->ndata);
            if(mid <= qindex->state->xpackettotal)
            {
                if(xpackets[mid].crc != docheader->crc)
                    qindex_update(qindex, mid, 1);
                else
                    qindex_update(qindex, mid, 0);
                xpackets[mid].status = docheader->status;
                xpackets[mid].crc = docheader->crc;
                ACCESS_LOGGER(qindex->logger, "update-index{gloablid:%lld mid:%d total:%d}", LL(docheader->globalid), mid, qindex->state->xpackettotal);
            }
            else
            {
                qindex->state->xpackettotal = mid;
                CHECK_XPACKETIO(qindex);
                if((xpackets = (XPACKET *)(qindex->xpacketio.map)))
                {
                    xpackets[mid].status = docheader->status;
                    xpackets[mid].crc = docheader->crc;
                    ACCESS_LOGGER(qindex->logger, "new-index{gloablid:%lld mid:%d}", LL(docheader->globalid), mid);
                }
            }
        }
        else
        {
            FATAL_LOGGER(qindex->logger, "Invalid document size:%d ndata:%d id:%lld crc:%d", docheader->size, block->ndata, LL(docheader->globalid), docheader->crc);
            _exit(-1);
        }
        MUTEX_UNLOCK(qindex->mutex);
    }
    return mid;
}
Пример #2
0
/* timeout handler*/
int benchmark_timeout_handler(CONN *conn, CB_DATA *packet, CB_DATA *cache, CB_DATA *chunk)
{
    if(conn)
    {
        if(cache && cache->data)
        {
            ACCESS_LOGGER(logger, "timeout on conn[%s:%d] uri[%s] via %d status:%d", conn->local_ip, conn->local_port, cache->data, conn->fd, conn->status);
        }
        else
        {
            ACCESS_LOGGER(logger, "timeout on conn[%s:%d] via %d status:%d", conn->local_ip, conn->local_port, conn->fd, conn->status);
        }
        ntimeout++;
        return http_check_over(conn);
    }
    return -1;
}
Пример #3
0
/* run procthread */
void procthread_run(void *arg)
{
    PROCTHREAD *pth = (PROCTHREAD *)arg;
    int i = 0, usec = 0, sec = 0;
    struct timeval tv = {0,0};
    struct timespec ts = {0, 0};
    int k = 0, n = 0, policy = 0;

    if(pth)
    {
        struct sched_param param;
        pthread_getschedparam(pthread_self(), &policy, &param);
        ACCESS_LOGGER(pth->logger, "Ready for running thread[%p] policy:%d SCHED_FIFO:%d SCHED_RR:%d SCHED_OTHER:%d", (void*)((long)(pth->threadid)), policy, SCHED_FIFO, SCHED_RR, SCHED_OTHER);
        pth->running_status = 1;
        if(pth->usec_sleep > 1000000) sec = pth->usec_sleep/1000000;
        usec = pth->usec_sleep % 1000000;
        tv.tv_sec = sec;
        tv.tv_usec = usec;
        ts.tv_sec = sec;
        ts.tv_nsec = (long)usec * 1000l;
        if(pth->have_evbase)
        {
            if(pth->cond > 0)
            {
                event_set(&(pth->event), pth->cond, E_READ|E_PERSIST,
                        (void *)pth, (void *)&procthread_event_handler);
                pth->evbase->add(pth->evbase, &(pth->event));
                if(pth->service->flag & SB_LOG_THREAD)
                {
                    char line[256];
                    if(pth == pth->service->outdaemon)
                    {
                        sprintf(line, "/tmp/%s_outdaemon.log", pth->service->service_name);
                        evbase_set_logfile(pth->evbase, line);
                    }
                    else
                    {
                        sprintf(line, "/tmp/%s_indaemon.log", pth->service->service_name);
                        evbase_set_logfile(pth->evbase, line);
                    }
                }
            }
            do
            {
                i = pth->evbase->loop(pth->evbase, 0, NULL);
                if(pth->service->flag & SB_LOG_THREAD)
                {
                    if(pth == pth->service->outdaemon)
                    {
                        ACCESS_LOGGER(pth->logger, "outdaemon_loop(%d/%d) q[%p]{total:%d left:%d}", i, k, pth->message_queue, QMTOTAL(pth->message_queue), QNLEFT(pth->message_queue));
                    }
                    else
                    {
                        ACCESS_LOGGER(pth->logger, "iodaemon_loop(%d/%d) q[%p]{total:%d left:%d}", i, k, pth->message_queue, QMTOTAL(pth->message_queue), QNLEFT(pth->message_queue));
                    }
                }
                if(pth->message_queue && (k = QMTOTAL(pth->message_queue)) > 0)
                {
                    qmessage_handler(pth->message_queue, pth->logger);
                }
                if((pth->service->flag & (SB_IO_NANOSLEEP|SB_IO_USLEEP|SB_IO_SELECT)) 
                        && n++ > pth->service->nworking_tosleep)
                {
                    if(pth->service->flag & SB_IO_NANOSLEEP) nanosleep(&ts, NULL); 
                    else if(pth->service->flag & SB_IO_USLEEP) usleep(pth->usec_sleep);
                    else if(pth->service->flag & SB_IO_SELECT) select(0, NULL, NULL, NULL, &tv);
                    n = 0;
                }
            }while(pth->running_status);
            if(pth == pth->service->outdaemon)
            {
                ACCESS_LOGGER(pth->logger, "Ready for stop outdaemons[%p]", pth);
            }
            else
            {
                ACCESS_LOGGER(pth->logger, "Ready for stop iodaemons[%p]", pth);
            }
        }
        else if(pth->listenfd > 0)
        {
            do
            {
                service_accept_handler(pth->service);
            }while(pth->running_status);
            ACCESS_LOGGER(pth->logger, "Ready for stop threads[acceptor]");
        }
        else
        {
            if(pth->use_cond_wait)
            {
                do
                {
                    //DEBUG_LOGGER(pth->logger, "starting cond-wait() threads[%p]->qmessage[%p]_handler(%d)", (void *)pth->threadid,pth->message_queue, QMTOTAL(pth->message_queue));
                    if(pth->message_queue && (k = QMTOTAL(pth->message_queue)) > 0)
                    {
                        qmessage_handler(pth->message_queue, pth->logger);
                        i = 1;
                    }
                    if(QMTOTAL(pth->message_queue) < 1) 
                    {
                        if(pth->service->flag & SB_USE_EVSIG)
                            evsig_wait(&(pth->evsig));
                        else if(pth->service->flag & SB_USE_COND)
                        {
                            MUTEX_WAIT(pth->mutex);
                        }
                        else
                            nanosleep(&ts, NULL);
                    }
                }while(pth->running_status);
                ACCESS_LOGGER(pth->logger, "ready to exit threads/daemons[%d]", pth->index);
            }
            else
            {
                do
                {
                    //DEBUG_LOGGER(pth->logger, "starting threads[%p]->qmessage[%p]_handler(%d)", (void *)(pth->threadid),pth->message_queue, QMTOTAL(pth->message_queue));
                    if(pth->evtimer){EVTIMER_CHECK(pth->evtimer);}
                    if(pth->message_queue && QMTOTAL(pth->message_queue) > 0)
                    {
                        qmessage_handler(pth->message_queue, pth->logger);
                    }
                    nanosleep(&ts, NULL);
                    //WARN_LOGGER(pth->logger, "over threads[%p]->qmessage[%p]_handler(%d)", (void *)(pth->threadid),pth->message_queue, QMTOTAL(pth->message_queue));
                }while(pth->running_status);
                ACCESS_LOGGER(pth->logger, "ready to exit threads/daemons[%d]", pth->index);
            }
        }
        if(pth->message_queue && QMTOTAL(pth->message_queue) > 0)
            qmessage_handler(pth->message_queue, pth->logger);
        ACCESS_LOGGER(pth->logger, "terminate threads[%d][%p] evbase[%p] qmessage[%p] ioqmessage[%p] qtotal:%d", pth->index, (void *)(pth->threadid), pth->evbase, pth->message_queue, pth->inqmessage, QMTOTAL(pth->message_queue));
    }
#ifdef HAVE_PTHREAD
    pthread_exit(NULL);
#endif
    return ;
}
Пример #4
0
/* add document */
int ibase_add_document(IBASE *ibase, IBDATA *block)
{
    int ret = -1, localid = 0, secid = 0, n = 0, newid = 0;
    DOCHEADER *docheader = NULL;
    MHEADER *mheader = NULL;
    IHEADER *iheader = NULL;
    char line[IB_LINE_MAX];
    off_t size = 0;

    if(ibase && block && block->ndata > 0 && (docheader = (DOCHEADER *)(block->data)) 
            && (secid = docheader->secid) >= 0 && secid < IB_SEC_MAX
            && ibase_check_index_state(ibase, docheader) == 0
            && docheader->globalid && (n = sprintf(line, "%lld", IBLL(docheader->globalid))))
    {
        if((localid = mmtrie_xadd(ibase->docmap, line, n)) > 0)
        {
            MUTEX_LOCK(ibase->mutex);
            if(localid <= ibase->state->docid) 
            {
                if(ibase->state->used_for == IB_USED_FOR_INDEXD)
                {
                    if((mheader = PMHEADER(ibase, localid))
                        && (iheader = PIHEADER(ibase, mheader->secid, mheader->docid)))
                    {
                        /* disabled */
                        if(docheader->status < 0)
                        {
                            mheader->status = -1;
                            iheader->status = -1;
                            DEBUG_LOGGER(ibase->logger, "Update docid:%d globalid:%lld status:%d", localid, IBLL(docheader->globalid), docheader->status);
                            ret = 0;
                        }
                        else if(docheader->crc != mheader->crc) 
                        {
                            ibase_del_index(ibase, secid, localid);
                            newid = ++(ibase->state->ids[secid]);
                            DEBUG_LOGGER(ibase->logger, "ready_reindex[%lld/%d]{crc:%d rank:%f slevel:%d category:%lld}", IBLL(docheader->globalid), localid, docheader->crc, docheader->rank, docheader->slevel, LLI(docheader->category));
                            mheader->docid = newid;
                            mheader->crc = docheader->crc;
                            ret = ibase_index(ibase, newid, block);
                            DEBUG_LOGGER(ibase->logger, "over_reindex[%lld/%d]{crc:%d rank:%f slevel:%d category:%lld}", IBLL(docheader->globalid), localid, docheader->crc, docheader->rank, docheader->slevel, LLI(docheader->category));
                        }
                        else
                        {
                            DEBUG_LOGGER(ibase->logger, "update_index[%lld/%d]{crc:%d rank:%f slevel:%d category:%lld}", IBLL(docheader->globalid), localid, docheader->crc, docheader->rank, docheader->slevel, LLI(docheader->category));
                            ret = ibase_update_index(ibase, mheader->docid, block);
                            DEBUG_LOGGER(ibase->logger, "over_update_index[%lld/%d]{crc:%d rank:%f slevel:%d category:%lld}", IBLL(docheader->globalid), localid, docheader->crc, docheader->rank, docheader->slevel, LLI(docheader->category));
                        }
                    }
                }
                else
                {
                    docheader->dbid = -1;
                    ret = ibase_index(ibase, localid, block);
                }
            }
            else
            {
                if(ibase->state->used_for == IB_USED_FOR_INDEXD)
                {
                    if(((off_t)localid * (off_t)sizeof(MHEADER)) >= ibase->mheadersio.end)
                    {
                        ibase->mheadersio.old = ibase->mheadersio.end;
                        size = (off_t)((localid / IB_HEADERS_BASE) + 1) 
                            * (off_t)IB_HEADERS_BASE * (off_t)sizeof(MHEADER);
                        ret = ftruncate(ibase->mheadersio.fd, size);
                        ibase->mheadersio.end = size;
                        memset(ibase->mheadersio.map + ibase->mheadersio.old, 0, 
                                ibase->mheadersio.end -  ibase->mheadersio.old);
                    }
                    if((mheader = PMHEADER(ibase, localid)))
                    {
                        mheader->status = 0;
                        mheader->docid = ++(ibase->state->ids[secid]);
                        mheader->secid = docheader->secid;
                        mheader->crc = docheader->crc;
                        DEBUG_LOGGER(ibase->logger, "new_index[%lld/%d]{crc:%d rank:%f slevel:%d category:%lld}", IBLL(docheader->globalid), localid, docheader->crc, docheader->rank, docheader->slevel, LLI(docheader->category));
                        ret = ibase_index(ibase, mheader->docid, block);
                    }
                }
                else
                {
                    ret = ibase_index(ibase, localid, block);
                }
                ibase->state->docid = localid;
            }
            MUTEX_UNLOCK(ibase->mutex);
            if(ibase->state->used_for != IB_USED_FOR_QPARSERD 
                    && ibase->state->mmsource_status != IB_MMSOURCE_NULL && localid > 0)
            {
                ACCESS_LOGGER(ibase->logger, "docid:%lld/%d c_size:%d c_zsize:%d size:%d", docheader->globalid, localid, docheader->content_size, docheader->content_zsize, docheader->nexts_off);
                docheader->size = docheader->nexts_off;
                ret = db_set_data(PDB(ibase->source), localid, block->data, docheader->size);
            }
            ret = 0;
        }
        else
        {
            FATAL_LOGGER(ibase->logger, "new_index[%lld]{crc:%d rank:%f slevel:%d category:%lld} failed, %s", IBLL(docheader->globalid), docheader->crc, docheader->rank, docheader->slevel, LLI(docheader->category), strerror(errno));

        }
    }
    return ret;
}
Пример #5
0
/* read upindex */
int qindex_read_upindex(QINDEX *qindex, int taskid, char *data, int *len, int *count)
{
    int ret = -1, mid = -1, nodeid = -1, id = 0, k = 0, n = 0, 
        left = 0, prev = 0, next = 0, *px = NULL;
    DOCHEADER *docheader = NULL;
    XPACKET *xpackets = NULL;
    QTNODE *nodes = NULL;
    QTASK *tasks = NULL;
    char *p = NULL;

    if(qindex && taskid >= 0 && data && taskid < Q_NODE_MAX * Q_TASKS_MAX
            && len && count && *len > 0)
    {
        MUTEX_LOCK(qindex->mutex);
        *count = 0;
        k = taskid % Q_TASKS_MAX;
        if((nodeid = (taskid / Q_TASKS_MAX)) < Q_NODE_MAX  && (nodes = qindex->state->nodes)
                && (tasks = qindex->state->nodes[nodeid].tasks) && tasks[k].status > 0
                && (xpackets =  (XPACKET *)(qindex->xpacketio.map)))
        {
            if(tasks[k].nupdates > 0 && tasks[k].upid != tasks[k].upover)
            {
                if((*len = db_read_data(PDB(qindex->update), taskid, p)) > 0)
                {
                    *count =  tasks[k].upcount;
                    ret = mid = tasks[k].upid;
                }
                else
                {
                    tasks[k].upid = tasks[k].upover = 0;
                }
            }
            else if(tasks[k].nqueue > 0 && tasks[k].mmqid > 0)
            {
                tasks[k].upcount = 0;
                left = *len;
                p = data;
                id = mmqueue_head(MMQ(qindex->mmqueue), tasks[k].mmqid, &mid);
                do
                {
                    if(id > 0 && mid > 0)
                    {
                        if(nodes[nodeid].type == Q_NODE_INDEXD && xpackets[mid].nodeid != nodeid)
                        {
                            prev = xpackets[mid].prev;
                            next = xpackets[mid].next;
                            FATAL_LOGGER(qindex->logger, "Invalid rootid:%d id:%d prev:%d[nodeid:%d] next:%d[nodeid:%d] xpacket[%d].nodeid[%d] to task[%s:%d].nodeid:%d nqueue:%d", tasks[k].mmqid, id, prev, xpackets[prev].nodeid, next, xpackets[next].nodeid, mid, xpackets[mid].nodeid, tasks[k].ip, tasks[k].port, nodeid, tasks[k].nqueue);
                            tasks[k].mmqid = 0;tasks[k].nqueue = 0;
                            break;
                        }
                        if(db_get_data_len(PDB(qindex->db), mid) > (left-Q_LEFT_LEN)) break;
                        tasks[k].upid = mid;
                        px = (int *)p;
                        p += sizeof(int);
                        docheader = (DOCHEADER *)p;
                        if((n = db_read_data(PDB(qindex->db), mid, p)) > sizeof(DOCHEADER)) 
                        {
                            ACCESS_LOGGER(qindex->logger, "update_index(%d) globalid:%lld mid:%d status:%d nodeid:%d task[%s:%d]", id,  LL(docheader->globalid), mid, xpackets[mid].status, xpackets[mid].nodeid, tasks[k].ip, tasks[k].port);
                            left -= n + sizeof(int);
                            p += n;
                            *px = n;
                            tasks[k].upcount++;
                        }
                        else
                        {
                            p -= sizeof(int);
                            FATAL_LOGGER(qindex->logger, "Invalid data id:%d to document:%lld", id, LL(docheader->globalid));
                            mid = -1;
                            //_exit(-1);
                            break;
                        }
                        mmqueue_pop(MMQ(qindex->mmqueue),tasks[k].mmqid, &mid);
                        tasks[k].nqueue--;
                        id = mmqueue_head(MMQ(qindex->mmqueue), tasks[k].mmqid, &mid);
                    }
                    else 
                    {
                        FATAL_LOGGER(qindex->logger, "Invalid qid:%d mid:%d", id, mid);
                        tasks[k].mmqid = 0;tasks[k].nqueue = 0;
                        mid = -1;
                        break;
                    }
                }while(tasks[k].nqueue > 0 && left > Q_LEFT_LEN && id > 0 && mid > 0);
                if((*count = tasks[k].upcount) > 0 && (*len -= left) > 0
                        && db_set_data(PDB(qindex->update), taskid, data, *len) >= 0)
                {
                    ret = tasks[k].upid;
                }
            }
            else ret = -1;
        }
        else ret = -2;
        MUTEX_UNLOCK(qindex->mutex);
    }
    return ret;
}
Пример #6
0
/* working for get_data() and push_index() */
int qindex_work(QINDEX *qindex, MINDEX *mindex)
{
    int ret = -1, i = 0, x = 0 , n = 0, mid = 0;
    int64_t *xid = NULL, key = 0, vlong = 0;
    BELEMENT *root = NULL, *sub = NULL;
    DOCHEADER *docheader = NULL;
    STERM *termlist = NULL;
    IBDATA block = {0};
    char *term = NULL;
    BRES *res = NULL;


    if(qindex && mindex && mindex_check(mindex) == 0)
    {
        if(mtask_pop(&(mindex->mtask)) > 0 && (xid = (int64_t *)mindex->mtask.packet)
                && mindex->mtask.length > sizeof(int64_t))
        {
            n = mindex->mtask.length/sizeof(int64_t);
            brequest_reset(&(mindex->request));
            brequest_append_keys(&(mindex->request), xid, n);
            brequest_finish(&(mindex->request));
            if((res = dbase_get_records(&(mindex->db), &(mindex->request))))
            {
                x = 0;
                while((root = dbase_next_record(res, root, &key))) 
                {
                    ACCESS_LOGGER(qindex->logger, "index_record[%d/%d] packetid:%d key:%lld", x, n, mindex->mtask.packetid, LLI(key));
                    vlong = 0;
                    if((sub = belement_find(root, qindex->db_key_name)))
                    {
                        belement_v_long(sub, &vlong);
                    }
                    if(key != vlong)
                    {
                        ACCESS_LOGGER(qindex->logger, "Invalid record[%d/%d] packetid:%d key:%lld/%lld", x, n, mindex->mtask.packetid, LLI(vlong), LLI(key));
                        return ret;
                    }
                    if((sub = belement_find(root, qindex->db_index_block_name))
                            && (block.ndata = belement_v_blob(sub, &(block.data))) > 0)
                    {
                        docheader = (DOCHEADER *)block.data;
                        termlist = (STERM *)(block.data + sizeof(DOCHEADER)
                                + docheader->nfields * sizeof(XFIELD));
                        term = block.data + docheader->textblock_off;
                        for(i = 0; i < docheader->nterms; i++)
                        {
                            termlist[i].termid = mmtrie_xadd(qindex->xdict, term, termlist[i].term_len); 
                            term += termlist[i].term_len;
                        }
                        mid = qindex_push_index(qindex, key, &block);
                        ACCESS_LOGGER(qindex->logger, "over_record[%d/%d] packetid:%d key:%lld", x, n, mindex->mtask.packetid, LLI(key));
                    }
                    else
                    {
                        FATAL_LOGGER(qindex->logger, "Invalid data feilds[%s]",  qindex->db_index_block_name);
                        return ret;
                    }
                    x++;
                }
                ret = 0;
                mtask_finish(&(mindex->mtask), 0);
            }
            else
            {
                FATAL_LOGGER(qindex->logger, "get_records(%d) failed, %s", mindex->mtask.packetid, strerror(errno));
                return ret;
            }
        }
    }
    return ret;
}