⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdk_heap.c

📁 这个是内存数据库中的一个管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
#line 67 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#include "monetdb_config.h"#include "gdk.h"static char *decompose_filename(str nme){	char *ext, *priv;	ext = strchr(nme, '.');	/* extract base and ext from heap file name */	if (ext) {		*ext++ = 0;		priv = strchr(ext, '.');		if (priv)			*priv = 0;	}	return ext;}#line 86 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 99 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"intHEAPalloc(Heap *h, size_t nitems, size_t itemsize){	char nme[PATHLENGTH], *ext = NULL;	if (h->filename) {		strcpy(nme, h->filename);		ext = decompose_filename(nme);	}	h->base = NULL;	h->maxsize = h->size = 1;	h->copied = 0;	if (itemsize)		h->maxsize = h->size = MAX(1, nitems) * itemsize;	h->free = 0;	/* check for overflow */	if (itemsize && nitems > (h->size/itemsize)) 		return -1;	/* when using anonymous vm we malloc we need 64K chunks, also we	 * 20% extra malloc */	if (h->size > GDK_mem_bigsize) {		h->maxsize = (size_t) ((double) h->maxsize * BATMARGIN) - 1;		h->maxsize = (1 + (h->maxsize >> 16)) << 16;	}	if (h->filename == NULL || (h->size < GDK_vm_minsize)) {		h->storage = STORE_MEM;		h->base = (char *) GDKmallocmax(h->size, &h->maxsize, 0);		if (h->base == 0) 			GDKerror("HEAPalloc: Insufficient space for HEAP.");	}	if (h->filename && h->base == NULL) {		char privext[PATHLENGTH], *of = h->filename;		FILE *fp;		h->filename = NULL;		sprintf(privext, "%s.priv", ext);		fp = GDKfilelocate(nme, "wb", privext);		if (fp != NULL) {			fclose(fp);			/* a non-persistent heap: we create a .priv but *not* MMAP_PRIV !!! */			h->storage = STORE_MMAP;			HEAPload(h, nme, ext, FALSE);		}		GDKfree(of);	}	h->newstorage = h->storage;	return (h->base == NULL) ? -1 : 0;}#line 151 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 166 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"intHEAPextend(Heap *h, size_t size){	char nme[PATHLENGTH], *ext = NULL;	if (h->filename) {		strcpy(nme, h->filename);		ext = decompose_filename(nme);	}	if (size <= h->size)		return 0;	if (h->storage & STORE_MMAP) {		/* memory mapped files extend: save and remap */		if (HEAPsave(h, nme, ext) < 0)			return -1;		HEAPfree(h);		h->maxsize = h->size = size;		if (HEAPload(h, nme, ext, FALSE) >= 0)			return 0;	} else {		/* extend a malloced heap, possibly switching over to file-mapped storage */		Heap bak = *h;		int can_mmap = (h->filename && size >= GDK_mem_bigsize);		int must_mmap = can_mmap && (size >= GDK_vm_minsize || (h->newstorage & STORE_MMAP));		h->size = size;		if (can_mmap) {			/* in anonymous vm, if have to realloc anyway, we reserve some extra space */			if (size > h->maxsize) {				h->maxsize = (size_t) ((double) size * BATMARGIN);			}			/* when using anonymous vm we malloc we need 64K chunks */			h->maxsize = (1 + ((h->maxsize-1) >> 16)) << 16;		} else {			h->maxsize = size; /* for normal GDKmalloc, maxsize = size */		}		/* try GDKrealloc if the heap size stays within reasonable limits */		if (!must_mmap) {			h->storage = STORE_MEM;			h->base = (char *) GDKreallocmax(h->base, size, &h->maxsize, 0);			if (h->base)				return 0;		}		/* too big: convert it to a disk-based temporary heap */		if (can_mmap) {			char privext[PATHLENGTH], *of = h->filename;			FILE *fp;			h->filename = NULL;			sprintf(privext, "%s.priv", ext);			fp = GDKfilelocate(nme, "wb", privext);			if (fp != NULL) {				fclose(fp);				/* a non-persistent heap: we create a .priv but *not* MMAP_PRIV !!! */				h->storage = STORE_MMAP;				if (HEAPload(h, nme, ext, FALSE) >= 0) {					memcpy(h->base, bak.base, bak.free);					HEAPfree(&bak);					return 0;				}			}			GDKfree(of);		}		*h = bak;	}	return -1;}#line 237 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 242 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"intHEAPcopy(Heap *dst, Heap *src){	if (HEAPalloc(dst, src->size, 1) == 0) {		dst->free = src->free;		memcpy(dst->base, src->base, src->free);		return 0;	}	return -1;}#line 254 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 259 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"intHEAPfree(Heap *h){	if (h->base) {		if (h->storage == STORE_MEM) {	/* plain memory */			GDKfree(h->base);		} else {	/* mapped file, or STORE_PRIV */			int ret = GDKmunmap(h->base, h->maxsize);			if (ret < 0) {				GDKsyserror("HEAPfree: %s was not mapped\n", h->filename);				assert(0);			}			IODEBUG THRprintf(GDKout, "#munmap(base=" PTRFMT ", size=" SZFMT ") = %d\n", PTRFMTCAST(void *)h->base, h->maxsize, ret);		}		h->base = NULL;	}	if (h->filename) {		GDKfree(h->filename);		h->filename = NULL;	}	return 0;}#line 284 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 297 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"intHEAPload(Heap *h, str nme, str ext, int trunc){	FILE *fp = (FILE *) GDKfilelocate(nme, "mrb", ext);	int ret = 0, desc_status = 0;	size_t truncsize = (1 + (((size_t) (h->free * 1.05)) >> REMAP_PAGE_MAXBITS)) << REMAP_PAGE_MAXBITS;	size_t minsize = (1 + ((h->size - 1) >> REMAP_PAGE_MAXBITS)) << REMAP_PAGE_MAXBITS;	int priv_storage = (h->storage == STORE_PRIV);	char priv[80]={0};	h->maxsize = h->size;	h->filename = NULL;	/* round up mmap heap sizes to REMAP_PAGE_MAXSIZE (usually 512KB) segments */	if ((h->storage & STORE_MMAP) && (minsize != h->size)) {		h->size = minsize;		h->maxsize = MAX(minsize, h->maxsize);	}	IODEBUG {		THRprintf(GDKout, "#HEAPload(%s.%s,storage=%d,free=" SZFMT ",size=" SZFMT ")\n", nme, ext, h->storage, h->free, h->size);	}	/* On some OSs (WIN32,Solaris), it is prohibited to write to a file that is open 	 * in MAP_PRIVATE (FILE_MAP_COPY) solution: read from a file renamed to .ext.priv 	 * .ex.priv files are now also used with STORE_MMAP mode on huge uncommitted BATs.	 */	strcpy(priv, ext);	strcat(priv, ".priv");	if (fp) {		ret = fclose(fp);	} else {		priv_storage = TRUE;	/* file may be in X.priv file iso X */	}	if (priv_storage) {		long_str path;		GDKfilepath(path, BATDIR, nme, priv);		if (fp == NULL) {			struct stat st;			ret = stat(path, &st);		} else {			/* silently remove any previous .ext.priv file */			(void) unlink(path);			ret = GDKmove(BATDIR, nme, ext, BATDIR, nme, priv);		}		ext = priv;	}	if (ret) {		return -1;	/* file could not be located */	}	/* legacy 2: some old repositories have wasted space => truncate during load */	if (trunc && truncsize < h->size) {		fp = (FILE *) GDKfilelocate(nme, "mrb+", ext);		if (fp) {			ret = ftruncate(fileno(fp), (off_t) truncsize);			IODEBUG THRprintf(GDKout, "#ftruncate(file=%s.%s, size=" SZFMT ") = %d\n", nme, ext, truncsize, ret);			fclose(fp);			if (ret == 0) {				h->size = h->maxsize = truncsize;				desc_status = 1;			}		}	}	h->base = (char *) GDKload(nme, ext, h->free, h->size, h->storage);	if (h->base == NULL) {		return -1;	/* file could  not be read satisfactorily */	}	h->newstorage = h->storage;	h->filename = (char *) GDKmalloc(strlen(nme) + strlen(ext) + 2);	sprintf(h->filename, "%s.%s", nme, ext);	return desc_status;	/* ok */}#line 373 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 384 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 385 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"int HEAPsave(Heap* h, str nme, str ext) {	int store = h->storage;	char *p = h->filename;	if (h->base == NULL) {		return -1;	} 	if (p == NULL || store == STORE_PRIV) {		/* anonymous or private VM is saved as if it were malloced */		store = STORE_MEM; 	}	IODEBUG {		THRprintf(GDKout, "#HEAPsave(%s.%s,storage=%d,free=" SZFMT ",size=" SZFMT ")\n", 			nme, ext, h->storage, h->free, h->size);	}	return GDKsave(nme, ext, h->base, h->free, store);}#line 403 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 407 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"intHEAPdelete(Heap *h, str o, str ext){	char ext2[64];	if (h->size <= 0) {                return 0;	}	if (h->base) {		if (h->copied == 0 && h->storage & STORE_MMAP) {			/* truncate file, so OS does not try to flush dirty data in mmap to file that is deleted anyway */			int ret, fd = GDKfdlocate(h->filename, "rb+", NULL);			IODEBUG THRprintf(GDKout, "#HEAPdelete(%s) GDKfdlocate(\"rb+\") = %d\n", h->filename, fd);			ret = ftruncate(fd, LL_CONSTANT(0));			IODEBUG THRprintf(GDKout, "#HEAPdelete(%s) ftruncate(%d,0LL) = %d\n", h->filename, fd, ret);			ret = close(fd);			IODEBUG THRprintf(GDKout, "#HEAPdelete(%s) close(%d) = %d\n", h->filename, fd, ret);		}		HEAPfree(h);	}	if (h->copied) {            return 0;        }	strcpy(ext2, ext);	strcat(ext2, ".priv");	return (GDKunlink(BATDIR, o, ext) == 0) | (GDKunlink(BATDIR, o, ext2) == 0)?0:-1;}int HEAPwarm(Heap *h) {	int bogus_result = 0;	if (h->storage & STORE_MMAP) {		/* touch the heap sequentially */                int *cur = (int*) h->base;                int *lim = (int*) (h->base + h->free) - 4096;		for(; cur<lim; cur+=4096) /* try to schedule 4 parallel memory accesses */			bogus_result += cur[0] + cur[1024] + cur[2048] + cur[3072];	}	return bogus_result;}#line 452 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 456 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"size_tHEAPvmsize(Heap *h){	if (h && h->free)		return h->maxsize;	return 0;}#line 465 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 470 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"size_tHEAPmemsize(Heap *h){	if (h && h->free && h->storage != STORE_MMAP)		return h->size;	return 0;}#line 479 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 498 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"/* #define DEBUG *//* #define TRACE */#define HEAPVERSION	20030408typedef struct heapheader {	size_t head;		/* index to first free block            */	int alignment;		/* alignment of objects on heap         */	size_t firstblock;	/* first block in heap                  */	int version;	int (*sizefcn) (ptr);	/* ADT function to ask length           */} HEADER32;typedef struct {	int version;	int alignment;	size_t head;	size_t firstblock;	int (*sizefcn) (ptr);} HEADER64;#if SIZEOF_SIZE_T==8typedef HEADER64 HEADER;typedef HEADER32 HEADER_OTHER;#elsetypedef HEADER32 HEADER;typedef HEADER64 HEADER_OTHER;#endiftypedef struct hfblock {	size_t size;		/* Size of this block in freelist        */	size_t next;		/* index of next block                   */} CHUNK;#line 532 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#define roundup_8(x)	(((x)+7)&~7)#define roundup_4(x)	(((x)+3)&~3)#define blocksize(h,p)	((p)->size)static INLINE size_troundup_num(size_t number, size_t alignment){	size_t rval = number + alignment - 1;	rval -= (rval % alignment);	return (rval);}size_tHEAP_private(Heap *h){	(void) h;	return roundup_8(sizeof(HEADER));}#ifdef TRACEstatic voidHEAP_printstatus(Heap *heap){	HEADER *hheader = HEAP_index(heap, 0, HEADER);	size_t block, cur_free = hheader->head;	CHUNK *blockp;	THRprintf(GDKout, "#HEAP has head " SZFMT " and alignment %d and size " SZFMT "\n", hheader->head, hheader->alignment, heap->free);	/*	   // Walk the blocklist;	 */	block = hheader->firstblock;	while (block < heap->free) {		blockp = HEAP_index(heap, block, CHUNK);		if (block == cur_free) {			THRprintf(GDKout, "#   free block at " PTRFMT " has size " SZFMT " and next " SZFMT "\n", PTRFMTCAST(void *)block, blockp->size, blockp->next);			cur_free = blockp->next;			block += blockp->size;		} else {			size_t size = blocksize(hheader, blockp);			THRprintf(GDKout, "#   block at " SZFMT " with size " SZFMT "\n", block, size);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -