commit-slab: introduce slabname##_peek() function
There is no API to ask "Does this commit have associated data in slab?". If an application wants to (1) parse just a few commits at the beginning of a process, (2) store data for only these commits, and then (3) start processing many commits, taking into account the data stored (for a few of them) in the slab, the application would use slabname##_at() to allocate a space to store data in (2), but there is no API other than slabname##_at() to use in step (3). This allocates and wastes new space for these commits the caller is only interested in checking if they have data stored in step (2). Introduce slabname##_peek(), which is similar to slabname##_at() but returns NULL when there is no data already associated to it in such a use case. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									282616c72d
								
							
						
					
					
						commit
						862e730ec1
					
				|  | @ -15,7 +15,13 @@ | |||
|  * - int *indegree_at(struct indegree *, struct commit *); | ||||
|  * | ||||
|  *   This function locates the data associated with the given commit in | ||||
|  *   the indegree slab, and returns the pointer to it. | ||||
|  *   the indegree slab, and returns the pointer to it.  The location to | ||||
|  *   store the data is allocated as necessary. | ||||
|  * | ||||
|  * - int *indegree_peek(struct indegree *, struct commit *); | ||||
|  * | ||||
|  *   This function is similar to indegree_at(), but it will return NULL | ||||
|  *   until a call to indegree_at() was made for the commit. | ||||
|  * | ||||
|  * - void init_indegree(struct indegree *); | ||||
|  *   void init_indegree_with_stride(struct indegree *, int); | ||||
|  | @ -80,8 +86,9 @@ static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s)		\ | |||
| 	s->slab = NULL;							\ | ||||
| }									\ | ||||
| 									\ | ||||
| static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,	\ | ||||
| 				       const struct commit *c)		\ | ||||
| static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s,	\ | ||||
| 						  const struct commit *c, \ | ||||
| 						  int add_if_missing)   \ | ||||
| {									\ | ||||
| 	int nth_slab, nth_slot;						\ | ||||
| 									\ | ||||
|  | @ -90,6 +97,8 @@ static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,	\ | |||
| 									\ | ||||
| 	if (s->slab_count <= nth_slab) {				\ | ||||
| 		int i;							\ | ||||
| 		if (!add_if_missing)					\ | ||||
| 			return NULL;					\ | ||||
| 		s->slab = xrealloc(s->slab,				\ | ||||
| 				   (nth_slab + 1) * sizeof(*s->slab));	\ | ||||
| 		stat_ ##slabname## realloc++;				\ | ||||
|  | @ -97,10 +106,25 @@ static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,	\ | |||
| 			s->slab[i] = NULL;				\ | ||||
| 		s->slab_count = nth_slab + 1;				\ | ||||
| 	}								\ | ||||
| 	if (!s->slab[nth_slab])						\ | ||||
| 	if (!s->slab[nth_slab]) {					\ | ||||
| 		if (!add_if_missing)					\ | ||||
| 			return NULL;					\ | ||||
| 		s->slab[nth_slab] = xcalloc(s->slab_size,		\ | ||||
| 					    sizeof(**s->slab) * s->stride);		\ | ||||
| 	return &s->slab[nth_slab][nth_slot * s->stride];				\ | ||||
| 	}								\ | ||||
| 	return &s->slab[nth_slab][nth_slot * s->stride];		\ | ||||
| }									\ | ||||
| 									\ | ||||
| static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s,	\ | ||||
| 					     const struct commit *c)	\ | ||||
| {									\ | ||||
| 	return slabname##_at_peek(s, c, 1);				\ | ||||
| }									\ | ||||
| 									\ | ||||
| static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s,	\ | ||||
| 					     const struct commit *c)	\ | ||||
| {									\ | ||||
| 	return slabname##_at_peek(s, c, 0);				\ | ||||
| }									\ | ||||
| 									\ | ||||
| static int stat_ ##slabname## realloc | ||||
|  |  | |||
							
								
								
									
										28
									
								
								commit.c
								
								
								
								
							
							
						
						
									
										28
									
								
								commit.c
								
								
								
								
							|  | @ -244,7 +244,12 @@ void set_commit_buffer(struct commit *commit, void *buffer, unsigned long size) | |||
|  | ||||
| const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep) | ||||
| { | ||||
| 	struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit); | ||||
| 	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); | ||||
| 	if (!v) { | ||||
| 		if (sizep) | ||||
| 			*sizep = 0; | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (sizep) | ||||
| 		*sizep = v->size; | ||||
| 	return v->buffer; | ||||
|  | @ -271,24 +276,31 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep) | |||
|  | ||||
| void unuse_commit_buffer(const struct commit *commit, const void *buffer) | ||||
| { | ||||
| 	struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit); | ||||
| 	if (v->buffer != buffer) | ||||
| 	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); | ||||
| 	if (!(v && v->buffer == buffer)) | ||||
| 		free((void *)buffer); | ||||
| } | ||||
|  | ||||
| void free_commit_buffer(struct commit *commit) | ||||
| { | ||||
| 	struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit); | ||||
| 	free(v->buffer); | ||||
| 	v->buffer = NULL; | ||||
| 	v->size = 0; | ||||
| 	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); | ||||
| 	if (v) { | ||||
| 		free(v->buffer); | ||||
| 		v->buffer = NULL; | ||||
| 		v->size = 0; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep) | ||||
| { | ||||
| 	struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit); | ||||
| 	struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); | ||||
| 	void *ret; | ||||
|  | ||||
| 	if (!v) { | ||||
| 		if (sizep) | ||||
| 			*sizep = 0; | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	ret = v->buffer; | ||||
| 	if (sizep) | ||||
| 		*sizep = v->size; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano