循环缓冲区Ç规模收缩 [英] C Shrinking size of circular buffer

查看:132
本文介绍了循环缓冲区Ç规模收缩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图完成了,简单地持有股票报价的数组循环缓冲器程序。不过,我似乎无法得到缩水循环缓冲区,当我的正确输出。

I am trying to finish up a circular buffer program that simply holds an array of stock quotes. However, I cannot seem to get my output correct when shrinking the circular buffer.

有收缩,缓冲区中的条件是,如果在缓冲器中的空间的3/4是自由的,由1/2缩小缓冲区。我的code为缩小/放大如下:

The condition for shrinking the buffer is if 3/4 of the space in the buffer is free, shrink the buffer by 1/2. My code for shrinking/enlarging is as follows:

void cbuf_update(cbuf *cb_ptr, unsigned int time, double rate){
    int threeFourths;
    threeFourths = (cb_ptr->maxSize/4)*3;

    if((cb_ptr->maxSize != startSize) && cb_ptr->freeSlots >= threeFourths){
        printf("Shrinking!\n");
        int newSize;
        newSize = (cb_ptr->maxSize/2)-1;
        cbuf *newBuffer = malloc(sizeof(cbuf) + newSize * sizeof(quote));
        newBuffer ->maxSize = (cb_ptr->maxSize/2);
        newBuffer ->freeSlots = newBuffer->maxSize - (cb_ptr->maxSize - cb_ptr->freeSlots);
        int x;
        int counter;
        int y;
        counter = 0;
        if(cb_ptr->end > cb_ptr->start){
            for(x = cb_ptr->end; x < cb_ptr->maxSize; x ++){
                if(cb_ptr->quoteBuffer[x].time != -1){
                    newBuffer->quoteBuffer[counter].time = cb_ptr->quoteBuffer[x].time;
                    newBuffer->quoteBuffer[counter].rate = cb_ptr->quoteBuffer[x].rate;
                    counter ++;
                }
            }   
            for(y = 0; y < cb_ptr->start; y++){
                if(cb_ptr->quoteBuffer[y].time != -1){
                    newBuffer->quoteBuffer[counter].time = cb_ptr->quoteBuffer[y].time;
                    newBuffer->quoteBuffer[counter].rate = cb_ptr->quoteBuffer[y].rate;
                    counter++;
                }
            }
        }
        if(cb_ptr->end < cb_ptr->start){
            //printf("second condition\n");
            for(x = cb_ptr->end; x < cb_ptr->start; x ++){
                if(cb_ptr->quoteBuffer[x].time != -1){

                    newBuffer->quoteBuffer[counter].time = cb_ptr->quoteBuffer[x].time;
                    newBuffer->quoteBuffer[counter].rate = cb_ptr->quoteBuffer[x].rate;
                    counter ++;
                }
            }       
        }
        newBuffer->start = counter;
        newBuffer->end = 0;
        cbuf_dump(newBuffer);
        *cb_ptr = *newBuffer;       

    }


    if(cb_ptr->freeSlots == 0){
        printf("EXPANDING CIRCULAR BUFFER!\n");
        int newSize;
        newSize = (cb_ptr->maxSize * 2) - 1;
        cbuf *newBuffer = malloc(sizeof(cbuf) + newSize * sizeof(quote));
        newBuffer->maxSize = cb_ptr->maxSize * 2;
        newBuffer->start = cb_ptr->start;
        newBuffer->end = cb_ptr->end;
        newBuffer->freeSlots = newBuffer->maxSize - cb_ptr->maxSize;
        int x;
        int counter;
        counter = 0;
        for(x = cb_ptr->end; x < cb_ptr->maxSize; x ++){
            newBuffer->quoteBuffer[counter].time = cb_ptr->quoteBuffer[x].time;
            newBuffer->quoteBuffer[counter].rate = cb_ptr->quoteBuffer[x].rate;
            counter ++;
        }
        int y;
        for(y = 0; y < cb_ptr->start; y ++){
            newBuffer->quoteBuffer[counter].time = cb_ptr->quoteBuffer[y].time;
            newBuffer->quoteBuffer[counter].rate = cb_ptr->quoteBuffer[y].rate;
            counter++;
        }
        newBuffer->start = cb_ptr->maxSize;
        newBuffer->end = 0;

        *cb_ptr = *newBuffer;



    }   


    //If the start pointer has reached the end of the array and there are still free slots back at the beginning of the array, loop back.   
    if(cb_ptr->start == cb_ptr->maxSize && cb_ptr->freeSlots > 0){
        //printf("Cannot insert time: %d\n", time);
        cb_ptr->start = 0;
    };
    cb_ptr->quoteBuffer[cb_ptr->start].time = time;
    cb_ptr->quoteBuffer[cb_ptr->start].rate = rate;
    cb_ptr->start = cb_ptr->start +1;
    cb_ptr->freeSlots = cb_ptr->freeSlots -1;

    //If any quote in the array is older than 5 minutes when compared to the current quote, flag it as null and move the end pointer up one.
    //Also, clear up a freeSlot.
    int x;
    for(x = cb_ptr->end; x < (cb_ptr->start); x ++){

        if((time) - (cb_ptr->quoteBuffer[x].time) >= fiveMin){
            cb_ptr->end = cb_ptr->end + 1;
            cb_ptr->quoteBuffer[x].time = -1;
            cb_ptr->quoteBuffer[x].rate = -1.00;
            cb_ptr->freeSlots = cb_ptr->freeSlots +1;
        }
    }


}

code倾倒缓冲区(打印出来)如下:

Code for dumping the buffer (printing it) is as follows:

void cbuf_dump(cbuf *cb_ptr){
    printf("*****\t DUMPING \t*****\n");

    if(cb_ptr->start > cb_ptr->end){
        //printf("first dump cond.\n");
        printf("start: %d\t end:%d\n", cb_ptr->start, cb_ptr->end);
        int x;
        for(x = cb_ptr->end; x<(cb_ptr->start); x++){
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
    }

    /*
    If the start pointer has been wrapped back around to the beginning of the circular buffer, then the end pointer must be at an index that is         greater than the start index. For this, we need to print out the data ranging from the end pointer to the end of the array, and then the        data from the start pointer to the end pointer provided the data isn't flagged as null (having -1 for both entries in the quote struct).
    */
    if(cb_ptr->end >= cb_ptr->start){
        //printf("Secondary condition\n");
        int x;
        for(x=cb_ptr->end; x < cb_ptr->maxSize; x ++){
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
        int y;
        for(y = 0; y < cb_ptr->start; y ++){
            if(cb_ptr->quoteBuffer[y].time != -1){
                printf("%d.) time = %d, \t rate = %f\n",y,(cb_ptr->quoteBuffer[y].time),(cb_ptr->quoteBuffer[y].rate));
            }
        }
    }

    //printf("freeslots = %d\n", cb_ptr->freeSlots);
}

终于,我的主要是:

and finally, my main is:

int main(){

    cbuf *cb1 ;

    cb1 = cbuf_init() ;
    cbuf_update(cb1, 60, 1.291) ;
    cbuf_update(cb1, 63, 1.287) ;
    cbuf_update(cb1, 63, 1.231) ;
    cbuf_update(cb1, 69, 1.229) ;
    cbuf_update(cb1, 72, 1.247) ;
    cbuf_update(cb1,361,1.291);
    cbuf_update(cb1, 411, 1.291) ;
    cbuf_update(cb1, 412, 1.281) ;
    cbuf_update(cb1, 413, 1.292) ;
    cbuf_update(cb1, 414, 1.284) ;
    cbuf_update(cb1, 414, 1.290) ;
    cbuf_update(cb1, 511, 1.241) ;
    cbuf_update(cb1, 512, 1.251) ;
    cbuf_update(cb1, 513, 1.232) ;
    cbuf_update(cb1, 514, 1.202) ;
    cbuf_update(cb1, 517, 1.119) ;
    cbuf_update(cb1, 551, 1.080) ;
    cbuf_update(cb1, 552, 1.081) ;
    cbuf_update(cb1, 553, 1.079) ;
    cbuf_update(cb1, 554, 1.088) ;
    cbuf_update(cb1, 561, 1.072) ;
    cbuf_update(cb1, 562, 1.113) ;
    cbuf_update(cb1, 563, 1.091) ;
    cbuf_update(cb1, 564, 1.092) ;
    cbuf_update(cb1, 571, 1.089) ;
    cbuf_update(cb1, 572, 1.073) ;
    cbuf_update(cb1, 573, 1.061) ;
    cbuf_update(cb1, 574, 1.111) ;
    cbuf_update(cb1, 581, 1.119) ;
    cbuf_update(cb1, 582, 1.123) ;
    cbuf_update(cb1, 583, 1.151) ;
    cbuf_update(cb1, 584, 1.153) ;  
    cbuf_dump(cb1);
    cbuf_update(cb1, 750, 1.200) ;
    cbuf_dump(cb1) ;
    cbuf_update(cb1, 818, 1.210) ;
    cbuf_dump(cb1) ;
    cbuf_update(cb1, 868, 1.230) ;
    cbuf_dump(cb1) ;
    cbuf_update(cb1, 878, 1.230) ;
    cbuf_dump(cb1) ;
    cbuf_update(cb1, 900, 1.240) ;
    cbuf_dump(cb1) ;
    cbuf_update(cb1, 2000, 1.240) ;
    cbuf_dump(cb1) ;
    return 0;

}

接近尾声的输出应该是:

The output towards the end should be:

*** Circular Buffer Dump ***
size = 11, max = 40
start = 19, end = 29

19: time = 571,  rate = 1.089000
20: time = 572,  rate = 1.073000
21: time = 573,  rate = 1.061000
22: time = 574,  rate = 1.111000
23: time = 581,  rate = 1.119000
24: time = 582,  rate = 1.123000
25: time = 583,  rate = 1.151000
26: time = 584,  rate = 1.153000
27: time = 750,  rate = 1.200000
28: time = 818,  rate = 1.210000
29: time = 868,  rate = 1.230000
****************************

Shrinking circular buffer: old max = 40, new max = 20


*** Circular Buffer Dump ***
size = 8, max = 20
start = 3, end = 10

3: time = 581,  rate = 1.119000
4: time = 582,  rate = 1.123000
5: time = 583,  rate = 1.151000
6: time = 584,  rate = 1.153000
7: time = 750,  rate = 1.200000
8: time = 818,  rate = 1.210000
9: time = 868,  rate = 1.230000
10: time = 878,  rate = 1.230000
****************************

Shrinking circular buffer: old max = 20, new max = 10


*** Circular Buffer Dump ***
size = 5, max = 10
start = 1, end = 5

1: time = 750,  rate = 1.200000
2: time = 818,  rate = 1.210000
3: time = 868,  rate = 1.230000
4: time = 878,  rate = 1.230000
5: time = 900,  rate = 1.240000
****************************



*** Circular Buffer Dump ***
size = 1, max = 10
start = 6, end = 6

6: time = 2000,  rate = 1.240000
****************************

不过,我的输出保持整理起来是这样的:

However, my output keeps finishing up like this:

*****    DUMPING    *****
start: 30    end:19
19.) time = 571,     rate = 1.089000
20.) time = 572,     rate = 1.073000
21.) time = 573,     rate = 1.061000
22.) time = 574,     rate = 1.111000
23.) time = 581,     rate = 1.119000
24.) time = 582,     rate = 1.123000
25.) time = 583,     rate = 1.151000
26.) time = 584,     rate = 1.153000
27.) time = 750,     rate = 1.200000
28.) time = 818,     rate = 1.210000
29.) time = 868,     rate = 1.230000
*****    DUMPING    *****
start: 31    end:23
23.) time = 581,     rate = 1.119000
24.) time = 582,     rate = 1.123000
25.) time = 583,     rate = 1.151000
26.) time = 584,     rate = 1.153000
27.) time = 750,     rate = 1.200000
28.) time = 818,     rate = 1.210000
29.) time = 868,     rate = 1.230000
30.) time = 878,     rate = 1.230000
Shrinking!
*****    DUMPING    *****
start: 9     end:8
8.) time = 900,      rate = 1.240000
Shrinking!
*****    DUMPING    *****
start: 2     end:1
1.) time = 2000,     rate = 1.240000

显然,格式是不同的,但数字应该匹配。我不能完全弄清楚,为什么只要900的时间将被添加到我的缓冲区,它似乎觉得时间codeS 581-878均大于五分钟走900(用于打印只打印标准最近在5分钟的时间跨度引号)。我意识到581-600显然将被丢弃,但剩下的应该还停留在缓冲区中。

Obviously the formatting is different, but the numbers should match up. I cant quite figure out why as soon as the time of 900 is added to my buffer, it seems to think the time codes 581-878 are all greater than five minutes away from 900 (the criteria for printing is only printing the most recent quotes in a 5 minute timespan). I realize 581-600 are obviously going to be discarded, but the rest should still remain in the buffer.

推荐答案

试试这个:

#include <stdio.h>
#include <stdlib.h>

enum { startSize = 0 };
enum { fiveMin = 5 * 60 };

typedef struct quote { int time; double rate; } quote;

typedef struct cbuf { int maxSize; int freeSlots; int start; int end; quote quoteBuffer[]; } cbuf;
static void cbuf_dump(cbuf *cb_ptr);

static void cbuf_update(cbuf **cb_dblptr, unsigned int time, double rate)
{
    cbuf *cb_ptr = *cb_dblptr;
    int threeFourths = (cb_ptr->maxSize/4)*3;

    if (cb_ptr->maxSize != startSize && cb_ptr->freeSlots >= threeFourths)
    {
        printf("Shrinking!\n");
        int newSize;
        newSize = (cb_ptr->maxSize/2)-1;
        cbuf *newBuffer = malloc(sizeof(cbuf) + newSize * sizeof(quote));
        newBuffer->maxSize = (cb_ptr->maxSize/2);
        newBuffer->freeSlots = newBuffer->maxSize - (cb_ptr->maxSize - cb_ptr->freeSlots);
        int counter = 0;
        if (cb_ptr->end > cb_ptr->start)
        {
            for (int x = cb_ptr->end; x < cb_ptr->maxSize; x++)
            {
                if (cb_ptr->quoteBuffer[x].time != -1)
                    newBuffer->quoteBuffer[counter++] = cb_ptr->quoteBuffer[x];
            }
            for (int y = 0; y < cb_ptr->start; y++)
            {
                if (cb_ptr->quoteBuffer[y].time != -1)
                    newBuffer->quoteBuffer[counter++] = cb_ptr->quoteBuffer[y];
            }
        }
        if (cb_ptr->end < cb_ptr->start)
        {

            for (int x = cb_ptr->end; x < cb_ptr->start; x++)
            {
                if (cb_ptr->quoteBuffer[x].time != -1)
                    newBuffer->quoteBuffer[counter++] = cb_ptr->quoteBuffer[x];
            }
        }
        newBuffer->start = counter;
        newBuffer->end = 0;
        cbuf_dump(newBuffer);
        *cb_dblptr = cb_ptr = newBuffer;
    }

    if (cb_ptr->freeSlots == 0)
    {
        printf("EXPANDING CIRCULAR BUFFER!\n");
        int newSize;
        newSize = (cb_ptr->maxSize * 2) - 1;
        cbuf *newBuffer = malloc(sizeof(cbuf) + newSize * sizeof(quote));
        newBuffer->maxSize = cb_ptr->maxSize * 2;
        newBuffer->start = cb_ptr->start;
        newBuffer->end = cb_ptr->end;
        newBuffer->freeSlots = newBuffer->maxSize - cb_ptr->maxSize;
        int counter = 0;
        for (int x = cb_ptr->end; x < cb_ptr->maxSize; x++)
            newBuffer->quoteBuffer[counter++] = cb_ptr->quoteBuffer[x];
        for (int y = 0; y < cb_ptr->start; y++)
            newBuffer->quoteBuffer[counter++] = cb_ptr->quoteBuffer[y];
        newBuffer->start = cb_ptr->maxSize;
        newBuffer->end = 0;
        *cb_dblptr = cb_ptr = newBuffer;
    }

    if (cb_ptr->start == cb_ptr->maxSize && cb_ptr->freeSlots > 0)
        cb_ptr->start = 0;
    cb_ptr->quoteBuffer[cb_ptr->start].time = time;
    cb_ptr->quoteBuffer[cb_ptr->start].rate = rate;
    cb_ptr->start = cb_ptr->start +1;
    cb_ptr->freeSlots = cb_ptr->freeSlots -1;

    for (int x = cb_ptr->end; x < (cb_ptr->start); x++)
    {
        if ((time) - (cb_ptr->quoteBuffer[x].time) >= fiveMin)
        {
            cb_ptr->end = cb_ptr->end + 1;
            cb_ptr->quoteBuffer[x].time = -1;
            cb_ptr->quoteBuffer[x].rate = -1.00;
            cb_ptr->freeSlots = cb_ptr->freeSlots +1;
        }
    }
}

static void cbuf_dump(cbuf *cb_ptr)
{
    printf("*****\t DUMPING \t*****\n");

    if (cb_ptr->start > cb_ptr->end)
    {
        printf("start: %d\t end:%d\n", cb_ptr->start, cb_ptr->end);
        for (int x = cb_ptr->end; x < cb_ptr->start; x++)
        {
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
    }

    if (cb_ptr->end >= cb_ptr->start)
    {
        for (int x = cb_ptr->end; x < cb_ptr->maxSize; x++)
        {
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
        for (int y = 0; y < cb_ptr->start; y++)
        {
            if (cb_ptr->quoteBuffer[y].time != -1)
            {
                printf("%d.) time = %d, \t rate = %f\n",y,(cb_ptr->quoteBuffer[y].time),(cb_ptr->quoteBuffer[y].rate));
            }
        }
    }
}

static cbuf *cbuf_init(void)
{
    return calloc(1, sizeof(cbuf));
}

int main(void)
{
    cbuf *cb1;

    cb1 = cbuf_init() ;
    cbuf_update(&cb1, 60, 1.291) ;
    cbuf_update(&cb1, 63, 1.287) ;
    cbuf_update(&cb1, 63, 1.231) ;
    cbuf_update(&cb1, 69, 1.229) ;
    cbuf_update(&cb1, 72, 1.247) ;
    cbuf_update(&cb1,361,1.291);
    cbuf_update(&cb1, 411, 1.291) ;
    cbuf_update(&cb1, 412, 1.281) ;
    cbuf_update(&cb1, 413, 1.292) ;
    cbuf_update(&cb1, 414, 1.284) ;
    cbuf_update(&cb1, 414, 1.290) ;
    cbuf_update(&cb1, 511, 1.241) ;
    cbuf_update(&cb1, 512, 1.251) ;
    cbuf_update(&cb1, 513, 1.232) ;
    cbuf_update(&cb1, 514, 1.202) ;
    cbuf_update(&cb1, 517, 1.119) ;
    cbuf_update(&cb1, 551, 1.080) ;
    cbuf_update(&cb1, 552, 1.081) ;
    cbuf_update(&cb1, 553, 1.079) ;
    cbuf_update(&cb1, 554, 1.088) ;
    cbuf_update(&cb1, 561, 1.072) ;
    cbuf_update(&cb1, 562, 1.113) ;
    cbuf_update(&cb1, 563, 1.091) ;
    cbuf_update(&cb1, 564, 1.092) ;
    cbuf_update(&cb1, 571, 1.089) ;
    cbuf_update(&cb1, 572, 1.073) ;
    cbuf_update(&cb1, 573, 1.061) ;
    cbuf_update(&cb1, 574, 1.111) ;
    cbuf_update(&cb1, 581, 1.119) ;
    cbuf_update(&cb1, 582, 1.123) ;
    cbuf_update(&cb1, 583, 1.151) ;
    cbuf_update(&cb1, 584, 1.153) ;
    cbuf_dump(cb1);
    cbuf_update(&cb1, 750, 1.200) ;
    cbuf_dump(cb1) ;
    cbuf_update(&cb1, 818, 1.210) ;
    cbuf_dump(cb1) ;
    cbuf_update(&cb1, 868, 1.230) ;
    cbuf_dump(cb1) ;
    cbuf_update(&cb1, 878, 1.230) ;
    cbuf_dump(cb1) ;
    cbuf_update(&cb1, 900, 1.240) ;
    cbuf_dump(cb1) ;
    cbuf_update(&cb1, 2000, 1.240) ;
    cbuf_dump(cb1) ;
    return 0;
}

这篇关于循环缓冲区Ç规模收缩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆