绑定文件的数组

对于大容量的数组,可以把它和一个文件绑定,内存中只缓存一些正在使用的片断。这样,数组的容量可以非常大。这是C++的一个实现:

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


class filearray {
    
    
private:
        struct page {
    
    
                int pageno;
                int tag;
                int *data;
        };

        FILE *fp;
        int count;
        int freenode;
        struct page node[8];

        int buf[100];

private:
        class cell {
    
    
        public:
                int index;
                filearray *ma;

                int operator=(int val) {
    
    
                        int *ip;
                        ip = ma->maparray(index);
                        *ip = val;
                        return val;
                }

                operator int() {
    
    
                        int *ip;
                        ip = ma->maparray(index);
                        return *ip;
                }
        };

        cell u;

public:
        filearray(FILE *fp);
        ~filearray();

        cell operator[](int index) {
    
    
                u.index = index;
                return u;
        }

private:
        int findlazy();
        void reset_tags();
        int *maparray(int index);
};


filearray::filearray(FILE *fp) :fp(fp) {
    
    
        count =1;
        freenode = 0xff;
        memset(&node[0], 0, sizeof(struct page)*8);
        for(int i=0; i<8; i++) {
    
    
                node[i].pageno=-1;
        }

        u.index=0;
        u.ma = this;
}

filearray::~filearray() {
    
    
        for(int i=0; i<8; i++) {
    
    
                if (node[i].pageno<0) continue;
                fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
                fread(buf, sizeof(int), 100, fp);
                if (memcmp(buf, node[i].data, sizeof(int)*100)!=0) {
    
    
                        fseek(fp, node[i].pageno*100*sizeof(int),
                                SEEK_SET);
                        fwrite(node[i].data, sizeof(int), 100, fp);
                }
        }
        fclose(fp);
}


int filearray::findlazy()
{
    
    
        int i;
        int lazy;
        int tag;

        lazy =0;
        tag= node[0].tag;
        for(i=1; i<8; i++) {
    
    
                if( node[i].tag<tag) {
    
    
                        tag= node[i].tag;
                        lazy=i;
                }
        }
        return lazy;
}


void filearray::reset_tags()
{
    
    
        int i, j;
        int index[8];
        for(i=0;i<8; i++) index[i]=i;

        for(i=0; i<8-1; i++) {
    
    
                for(j=i+1;j<8; j++) {
    
    
                        int t;
                        if (node[index[i]].tag >node[index[j]].tag) {
    
    
                                t= index[j];
                                index[j] = index[i];
                                index[i]= t;
                        }
                }
        }

        for(i=0; i<8; i++) {
    
    
                printf("%d\t", node[index[i]].tag);
        }
        printf("\n");

        for(i=0; i<8; i++) {
    
    
                node[index[i]].tag=i;
        }
        count =8;
}


int *filearray::maparray(int index)
{
    
    
        int i;
        int pageno;

        pageno = index/100;
        for(i =0; i<8;  i++)  {
    
    
                if (node[i].pageno==pageno) {
    
    
                find:
                        node[i].tag = count++;
                        if( count <0) {
    
    
                                reset_tags();
                        }
                        return &node[i].data[index%100];
                }
        }
        if (freenode) {
    
    
                int mask;
                mask=1;
                for(i=0; i<8; i++) {
    
    
                        if (freenode &mask) {
    
    
                                freenode ^= mask;
                                node[i].pageno = pageno;
                                node[i].data = (int *)malloc(sizeof(int)*100);
                                if (node[i].data==NULL) {
    
    
                                        printf("malloc error\n");
                                        exit(0);
                                }
printf("use free node %d\n", i);
                                goto find;
                        }
                        mask <<=1;
                }
        }
        i  = findlazy();

        fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
        fread(buf, sizeof(int), 100, fp);
        if (memcmp(buf, node[i].data, sizeof(int)*100)!=0) {
    
    
                fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
                fwrite(node[i].data, sizeof(int), 100, fp);
        }
        node[i].pageno = pageno;
        fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
        fread(node[i].data, sizeof(int), 100, fp);
        goto find;
}



int main()
{
    
    
        int i;
        int val;
        char *name;
        FILE *fp;

        name = "array.dat";
        fp = fopen(name, "w+b");
        if (!fp) {
    
    
                printf("can not open %s\n", name);
                exit(0);
        }

        filearray arr(fp);

        for(i=0; i<100000; i++) {
    
    
                arr[i]  = 10000000+ i;
        }

        for(i=0; i<100/2; i++) {
    
    
                val = arr[((49-i)*2000)];
                printf("%d\n", val);
        }



arr[100]=200;
arr[200]= arr[100]+4;

printf("%d, %d", int(arr[100]),int(arr[100]*arr[200]));

        return 0;
}

Guess you like

Origin blog.csdn.net/aaasssdddd96/article/details/108985791