// ====================================================================== // // Copyright (c) 1998 The CGAL Consortium // // This software and related documentation is part of an INTERNAL release // of the Computational Geometry Algorithms Library (CGAL). It is not // intended for general use. // // ---------------------------------------------------------------------- // // release : // release_date : 2000, August 11 // // file : include/CGAL/internal_memory.h // package : ExternalMemoryStructures (0.631) // maintainer : Philipp Kramer // chapter : $CGAL_Chapter: Basic / External Data Structures $ // source : // revision : $Revision$ // revision_date : $Date$ // author(s) : Gabriele Neyer // // coordinator : ETH Zurich (Peter Widmayer ) // // Provide access structure for data in a file. // ====================================================================== #ifndef __INTERNAL_MEMORY_H__ #define __INTERNAL_MEMORY_H__ #include #include #include #include #include CGAL_BEGIN_NAMESPACE //first written element in the data file. It stores implicitly //a list of deleted elements by link pfirst. The element pfirst //points to then stores a link to the next deleted element. //plast always keeps the end of file position. class Theader{ public: typedef ptrdiff_t difference_type; int pfirst; //position of first deleted element int plast; //end of file position int number_of_elements; size_t size(void) { return 3*sizeof(int); } Theader() : pfirst(-1), plast(0), number_of_elements(0) {} void read(char *s){ int sint=(int)sizeof(int); char *from_int=new char[sint]; int i,r=0; for (i=0; i(from_bool)); for (i=0; i=number_of_pages) { char *tmp_data = new char[2*number_of_pages*(IO_pagesize+elem.size()) +header.size()]; memcpy(tmp_data,raw_data, number_of_pages*(IO_pagesize+elem.size())+header.size()); delete [] raw_data; raw_data=tmp_data; number_of_pages=2*number_of_pages; } pos = header.plast; header.plast++; header.write(raw_data); } else { oldelem.read(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); header.pfirst=oldelem.pnext; header.write(raw_data); } elem.write(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); memcpy(raw_data+(pos)*(elem.size()+IO_pagesize)+header.size()+elem.size(), *x,IO_pagesize); return pos; } //an new element is inserted. Its position is returned. difference_type get_pos() { difference_type pos = header.pfirst; Telem oldelem; header.number_of_elements++; if (pos==-1){ if(header.number_of_elements-1>=number_of_pages) //make raw_data larger! { char *tmp_data = new char[2*number_of_pages*(IO_pagesize+elem.size()) +header.size()]; memcpy(tmp_data,raw_data, number_of_pages*(IO_pagesize+elem.size())+header.size()); delete [] raw_data; raw_data=tmp_data; number_of_pages=2*number_of_pages; } pos = header.plast; header.plast++; header.write(raw_data); } else { oldelem.read(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); header.pfirst=oldelem.pnext; header.write(raw_data); } return pos; } //an new element is inserted. Its position is returned. bool insert(difference_type pos, char** x) { elem.deleted = false; elem.pnext=-1; elem.t=time(&elem.t); elem.write(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); memcpy(raw_data+(pos)*(elem.size()+IO_pagesize)+header.size()+elem.size(), *x,IO_pagesize); return true; } //returns the number of valid elements in the file. difference_type number_of_elements(){ return header.number_of_elements; } // the element associated with position pos is returned. // x has to provide size space for writing bool get(difference_type pos, char **x) { if(pos <0 || pos > header.plast) return false; else{ elem.read(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); if(elem.deleted) return false; memcpy(*x,raw_data+(pos)*(elem.size()+IO_pagesize)+header.size() +elem.size(),IO_pagesize); } return true; } // the element at position pos is updated with x. bool update(difference_type pos, char **x){ bool ret = true; if(pos <0 || pos > header.plast) return false; else{ elem.read(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); if(elem.deleted) { elem.deleted=true; ret = false; } elem.write(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); memcpy(raw_data+(pos)*(elem.size()+IO_pagesize)+header.size()+elem.size() ,*x,IO_pagesize); } return ret; } //the element at position pos is declared deleted. Its free place //is stored in the header. bool erase(difference_type pos) { if(pos <0 || pos > header.plast) return false; else{ elem.read(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); if(elem.deleted) return false; if(!elem.deleted) header.number_of_elements--; elem.deleted = true; elem.pnext=header.pfirst; header.pfirst=pos; elem.write(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); header.write(raw_data); } return true; } //returns true if the element at position pos is deleted. bool deleted(difference_type pos) { if(pos <0 || pos > header.plast) return true; else{ elem.read(raw_data+(pos)*(elem.size() + IO_pagesize) + header.size()); if(elem.deleted) return true; } return false; } }; CGAL_END_NAMESPACE #endif