There is nothing to worry about. Considering a previous problem, it is necessary to use STD: vector to store data. If the stored data volume is large or there is not enough memory, what should I do, considering the concept of virtual memory when learning OS, it seems to be a good solution, so I wrote a small program to implement this idea. The following is the c ++ code
Only the specified amount of recently used data is retained in the memory, and the remaining data is saved to a file. If the accessed data is stored, it can be directly extracted from the memory, if the data is not in the memory, first load the data to the memory,
The Code also considers the swap efficiency between memory and files, for example:
The data range in the memory is [10, 20]. For the 8th elements that I need to access, it is assumed that the elements around the 8th elements will be frequently accessed in the near future, therefore, when loading data, load the surrounding elements to the memory. Therefore, you need to load the data in the range [8-10/2, 8 + 10/2] to the memory, however, the data in the range [] is already in the memory, so you only need to load the data in the range [] to the memory,
The following is the specific code.
++ ++ ++
// Myqueue. h: interface for the cmyqueue class.
//
//////////////////////////////////////// //////////////////////////////
# Ifndef _ myqueue_h_included _
# DEFINE _ myqueue_h_included _
/*
FIFO with a length limit.
When the inserted element exceeds the specified length, it overwrites the Header element.
*/
Template <class T>
Class cmyqueue
{
Public:
Cmyqueue (INT Len)
{
Mi_maxlen = Len;
Clear ();
Mp_list = new T [mi_maxlen];
};
Virtual ~ Cmyqueue ()
{
Clear ();
If (mp_list! = NULL)
{
Delete [] mp_list;
}
};
Void offset (INT offset)
{
Mi_headptr = (mi_headptr + offset) % mi_maxlen;
Mi_tailptr = (mi_tailptr + offset) % mi_maxlen;
If (mi_headptr <0)
{
Mi_headptr = mi_maxlen + mi_headptr;
}
If (mi_tailptr <0)
{
Mi_tailptr = mi_maxlen + mi_tailptr;
}
}
Int Len ()
{
Return mi_elenum;
}
Void clear ()
{
Mi_elenum = 0;
Mi_headptr = 0;
Mi_tailptr = 0;
};
/*
Insert element
*/
Void pushback (const T & T)
{
Mp_list [mi_tailptr] = T;
Mi_tailptr = (mi_tailptr + 1) % mi_maxlen;
If (mi_elenum <mi_maxlen)
{
Mi_elenum ++;
}
Else
{
Mi_headptr = (mi_headptr + 1) % mi_maxlen;
}
};
/*
Extract Element
*/
T & poptail ()
{
If (mi_elenum <= 0)
Return mp_list [0];
Int ntmp = mi_headptr;
Mi_headptr = (mi_headptr + 1) % mi_maxlen;
Mi_elenum --;
Return mp_list [ntmp];
};
/*
Access
*/
T & operator [] (INT index)
{
If (index <0 | index> mi_maxlen)
Return mp_list [0];
Int ntmp = (mi_headptr + index) % mi_maxlen;
Return mp_list [ntmp];
};
Protected:
Int mi_headptr;
Int mi_tailptr;
Int mi_elenum;
Int mi_maxlen;
T * mp_list;
};
# Endif
++ ++ ++
// Vmm. h: interface for the cvmm class.
//
//////////////////////////////////////// //////////////////////////////
# Ifndef _ my_vmm_h_included _
# DEFINE _ my_vmm_h_included _
# Include "myqueue. H"
# Define fname (t) # T
/*
Virtual Memory implementation:
Restrictions:
1. The length of T-type data is required
2. The T-type data supports the memcpy memset operation.
*/
Template <class T>
Class cvmm
{
Public:
Cvmm (INT nmemlen= 1024): mc_memlist (nmemlen)
{
Mi_memlen = nmemlen;
Clear ();
Mp_readptr = NULL;
Mp_writeptr = NULL;
Sprintf (ms_filename, "% S _ % 04d. vmm", fname (t), sizeof (t ));
Clearfile ();
};
Virtual ~ Cvmm ()
{
Clear ();
Closereadvmfile ();
Closewritevmfile ();
};
Void pushback (const T & T)
{
If (mi_reallen <mi_memlen)
{
Mc_memlist.pushback (t );
Mi_reallen ++;
}
Else if (mi_reallen = mi_memlen)
{
If (mi_filelen <= mi_rangemin)
Memorytofile (mc_memlist.poptail ());
Mc_memlist.pushback (t );
Mi_reallen ++;
Mi_rangemin ++;
}
Else if (mi_reallen> mi_memlen)
{
If (mi_reallen-mi_rangemin = mi_memlen)
{
If (mi_filelen <= mi_rangemin)
Memorytofile (mc_memlist.poptail (); // write the file
Mc_memlist.pushback (t );
Mi_reallen ++;
Mi_rangemin ++;
}
Else
{
Mi_reallen ++;
Mi_rangemin = mi_reallen-mi_memlen;
Suffixftom (mi_reallen-mi_memlen, mi_reallen );
Mc_memlist.pushback (t );
}
}
};
Void clear ()
{
Mi_filelen = 0;
Mi_reallen = 0;
Mi_rangemin = 0;
Mc_memlist.clear ();
};
Int size ()
{
Return mi_reallen;
};
T & operator [] (INT index)
{
Static T (0 );
If (index <0 | index> = mi_reallen)
Return T;
If (index> = mi_rangemin & index <mi_rangemin + mi_memlen)
Return mc_memlist [index-mi_rangemin];
If (mi_filelen <mi_rangemin + mi_memlen)
Memorytofile ();
Int naddr;
If (index <mi_rangemin)
{
Naddr = index-mi_memlen/2;
If (naddr <0)
Naddr = 0;
Prefixftom (naddr, naddr + mi_memlen );
}
Else if (index> = mi_rangemin + mi_memlen)
{
Naddr = index + mi_memlen/2;
If (naddr> = mi_reallen)
Naddr = mi_reallen;
Suffixftom (naddr-mi_memlen, naddr );
}
Return mc_memlist [index-mi_rangemin];
};
Protected:
Void clearfile ()
{
Closereadvmfile ();
Closewritevmfile ();
Mp_writeptr = fopen (ms_filename, "W ");
Closewritevmfile ();
}
Void closereadvmfile ()
{
If (mp_readptr! = NULL)
{
Fclose (mp_readptr );
Mp_readptr = NULL;
}
}
Void closewritevmfile ()
{
If (mp_writeptr! = NULL)
{
Fclose (mp_writeptr );
Mp_writeptr = NULL;
}
}
/*
Handling of open exception not considered
*/
Bool openreadvmfile ()
{
Closewritevmfile ();
If (mp_readptr! = NULL)
Return true;
Mp_readptr = fopen (ms_filename, "rb ");
If (mp_readptr = NULL)
Return false;
Return true;
};
/*
Handling of open exception not considered
*/
Bool openwritevmfile ()
{
Closereadvmfile ();
If (mp_writeptr! = NULL)
Return true;
Mp_writeptr = fopen (ms_filename, "AB ");
If (mp_writeptr = NULL)
Return false;
Return true;
};
Bool memorytofile ()
{
Int nindex1 = mi_filelen;
Int nindex2 = mi_filelen-mi_rangemin;
Int ndata;
While (nindex1 <mi_rangemin + mi_memlen)
{
Ndata = mc_memlist [nindex2];
Memorytofile (ndata );
Nindex1 ++;
Nindex2 ++;
}
Return true;
}
Bool memorytofile (const T & T)
{
Openwritevmfile ();
Fwrite (char *) & T, sizeof (t), 1, mp_writeptr );
Mi_filelen ++;
Return true;
}
Bool prefixftom (INT nstart, int nend)
{
If (nend <= mi_rangemin)
{
// No overlapped data
Filetomemory (nstart, nend );
}
Else
{
Filetomemory (nstart, mi_rangemin );
Mc_memlist.offset (nend-mi_rangemin );
}
Mi_rangemin = nstart;
Return true;
}
Bool suffixftom (INT nstart, int nend)
{
If (mi_rangemin + mi_memlen <= nstart)
{
// No overlapped data
Filetomemory (nstart, nend );
}
Else
{
Filetomemory (mi_rangemin + mi_memlen, nend );
}
Mi_rangemin = nstart;
Return true;
}
// [Nstart, nend)
Bool filetomemory (INT nstart, int nend)
{
Openreadvmfile ();
If (nstart! = 0)
Fseek (mp_readptr, nstart * sizeof (t), seek_set );
T tmpele;
Int ncount = nstart;
Int nsize;
While (! Feof (mp_readptr) & ncount <nend)
{
Nsize = fread (& tmpele, sizeof (t), 1, mp_readptr );
If (nsize = 0)
Break;
Mc_memlist.pushback (tmpele );
Ncount ++;
}
Return true;
}
Protected:
File * mp_readptr;
File * mp_writeptr;
Char ms_filename [2, 512];
Cmyqueue <t> mc_memlist;
Int mi_reallen;
Int mi_filelen;
Int mi_memlen;
Int mi_rangemin;
};
# Endif
++ ++ =
# Include "vmm. H"
Int main (INT argc, char * argv [])
{
Printf ("Hello world! /N ");
Cvmm <int> MList (5 );
MList. pushback (1 );
MList. pushback (2 );
MList. pushback (3 );
MList. pushback (4 );
Printf ("[% d]/n", MList [0]); // 1
Printf ("[% d]/n", MList [3]); // 4
MList. pushback (5 );
Printf ("[% d]/n", MList [0]); // 1
Printf ("[% d]/n", MList [4]); // 5
MList. pushback (6 );
Printf ("[% d]/n", MList [1]); // 2
Printf ("[% d]/n", MList [5]); // 6
Printf ("[% d]/n", MList [0]); // 1
MList. pushback (7 );
MList. pushback (8 );
Printf ("[% d]/n", MList [6]); // 7
Printf ("[% d]/n", MList [0]); // 1
MList. pushback (9 );
Printf ("[% d]/n", MList [0]); // 1
Return 0;
}