C 缩小循环缓冲区的大小

标签 c arrays

我正在尝试完成一个只包含一组股票报价的循环缓冲区程序。但是,在缩小循环缓冲区时,我似乎无法正确输出。

收缩缓冲区的条件是如果缓冲区中有 3/4 的空间是空闲的,则将缓冲区收缩 1/2。我的缩小/放大代码如下:

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;
        }
    }


}

转储缓冲区(打印)的代码如下:

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);
}

最后,我的主要是:

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;

}

最后的输出应该是:

*** 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
****************************

但是,我的输出一直这样结束:

*****    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 的时间添加到我的缓冲区,它似乎认为时间代码 581-878 都比 900 大了五分钟(打印标准只打印最近的报价在 5 分钟的时间跨度内)。我意识到 581-600 显然要被丢弃,但其余部分仍应保留在缓冲区中。

最佳答案

试试这个:

#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;
}

关于C 缩小循环缓冲区的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16291959/

相关文章:

ios - Swift 按键排序字典数组,其中值是可选的 AnyObject

C - 创建动态矩阵函数的问题

将两个命令与管道组合

c - 尝试了解 undcl 的工作原理(来自 K&R 书 - 第 5-12 章复杂声明)

jQuery 将数组作为函数中的参数传递

java - 文件到字节数组

c++ - 使用 -1 初始化结构或数组的无符号 {} 初始化

camshift 对象跟踪问题

c - char ** 对象是如何保存的?

c - 如何在 C 中创建多维动态分配数组?