// Copyright (c) 1998 ETH Zurich (Switzerland). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Gabriele Neyer #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