Exemplo n.º 1
0
/*
 * llist_search: search for entry with val that matches
 * according to compare_function in list llist. Return
 * match in e.
 */
int llist_search(llist_entry **llist, void *val,
                 int (*compare_function)(const char *, const char *),
                 llist_entry **e)
{
    llist_entry *ei;

    for (ei = (*llist); ei != NULL; ei = ei->next)
        if (compare_function(ei->val, val) == 0) {
            (*e) = ei;
            return 0;
        }
    return -1;
}
Exemplo n.º 2
0
static int ds_zval_compare_func(const void *a, const void *b)
{
    zval retval;

    zval *x = (zval*) a;
    zval *y = (zval*) b;

    if (compare_function(&retval, x, y) == SUCCESS) {
        return (int) zval_get_long(&retval);
    }

    return 0;
}
Exemplo n.º 3
0
int
llist_sort(llist_entry *llist, int (*compare_function)(llist_entry *, llist_entry *))
{
    llist_entry     *lle1, *lle2;
    void            *tmp_val;

    for (lle1 = llist; lle1 != NULL; lle1 = lle1->next) {
        for (lle2 = lle1->next; lle2 != NULL; lle2 = lle2->next) {
            if (compare_function(lle1, lle2) == 1) {
                tmp_val = lle1->val;
                lle1->val = lle2->val;
                lle2->val = tmp_val;
            }
        }
    }
    return 0;
}
Exemplo n.º 4
0
void merge_sort(void* Array, size_t size_of_array, size_t size_of_data, int (*compare_function)(const void*, const void*))
{
    if(size_of_array <= 1)
        return;
    else
    {
        void* Middle = Array + (size_of_array / 2) * size_of_data;
        void* End = Array + size_of_array * size_of_data;
        merge_sort((void*)Array  , size_of_array / 2                 , size_of_data, compare_function);
        merge_sort((void*)Middle , size_of_array - size_of_array / 2 , size_of_data, compare_function);
        void *buffer = malloc(size_of_array * size_of_data);
        void *first_iterator = Array, *second_iterator = Middle, *inserter = buffer;
        while((first_iterator < Middle) && (second_iterator < End))
        {
            if(compare_function(first_iterator, second_iterator) <= 0)
            {
                memcpy(inserter, first_iterator, size_of_data);
                first_iterator += size_of_data;
                inserter += size_of_data;
            }
            else
            {
                memcpy(inserter, second_iterator, size_of_data);
                second_iterator += size_of_data;
                inserter += size_of_data;
            }
        }
        while(first_iterator < Middle)
        {
            memcpy(inserter, first_iterator, size_of_data);
            first_iterator += size_of_data;
            inserter += size_of_data;
        }
        while(second_iterator < End)
        {
            memcpy(inserter, second_iterator, size_of_data);
            second_iterator += size_of_data;
            inserter += size_of_data;
        }
        memcpy(Array, buffer, size_of_array * size_of_data);
        free(buffer);
    }
}
Exemplo n.º 5
0
static int spl_ptr_heap_zval_min_cmp(zval *a, zval *b, zval *object) { /* {{{ */
	zval result;

	if (EG(exception)) {
		return 0;
	}

	if (object) {
		spl_heap_object *heap_object = Z_SPLHEAP_P(object);
		if (heap_object->fptr_cmp) {
			zend_long lval = 0;
			if (spl_ptr_heap_cmp_cb_helper(object, heap_object, a, b, &lval) == FAILURE) {
				/* exception or call failure */
				return 0;
			}
			return lval > 0 ? 1 : (lval < 0 ? -1 : 0);
		}
	}

	compare_function(&result, b, a);
	return (int)Z_LVAL(result);
}
Exemplo n.º 6
0
list_t * list_sort(list_t *list, compare_function_t *compare_function)
{
    if (list == NULL) {
        //TODO throw an error
        return NULL;
    }

    if (list->head == NULL) {
        return list;
    }

    if (compare_function == NULL) {
        //TODO throw an error
        return NULL;
    }
    
    //The sort is done using bubble sort
    //TODO Change to a better sorting algorithm 

    bool swapped;

    do {
        swapped = false;

        list_elem_t *elem = list->head;
       
        while (elem->next != NULL) {
            if (compare_function(elem->value, elem->next->value) > 0) {
                list_swap_elements(list, elem, elem->next);
                swapped = true;
            } else {
                elem = elem->next;
            }
        }
    } while (swapped); 

    return list;
}
Exemplo n.º 7
0
VALUE php_value_obj_equal(VALUE self, VALUE rhs) {
    zval *lhs_zv;
    zval *rhs_zv;
    zval *result;
    int cmp_ret;

    lhs_zv = get_zval(self);
    if (lhs_zv == NULL) {
        return Qnil;
    }

    if (cPhpEmbedValue == CLASS_OF(rhs)) {
        rhs_zv = get_zval(rhs);
    } else {
        rhs_zv = value_to_zval(rhs);
    }

    MAKE_STD_ZVAL(result);
    compare_function(result, lhs_zv, rhs_zv TSRMLS_CC);
    cmp_ret = Z_LVAL_P(result);
    FREE_ZVAL(result);

    return cmp_ret == 0 ? Qtrue : Qfalse;
}
Exemplo n.º 8
0
/* Given a type-library, merge it into the current engine state */
PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepage TSRMLS_DC)
{
	int i, j, interfaces;
	TYPEKIND pTKind;
	ITypeInfo *TypeInfo;
	VARDESC *pVarDesc;
	UINT NameCount;
	BSTR bstr_ids;
	zend_constant c;
	zval *exists, results, value;
	char *const_name;
	int len;

	if (TL == NULL) {
		return FAILURE;
	}

	interfaces = ITypeLib_GetTypeInfoCount(TL);
	for (i = 0; i < interfaces; i++) {
		ITypeLib_GetTypeInfoType(TL, i, &pTKind);
		if (pTKind == TKIND_ENUM) {
			ITypeLib_GetTypeInfo(TL, i, &TypeInfo);
			for (j = 0; ; j++) {
				if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) {
					break;
				}
				ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);
				if (NameCount != 1) {
					ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
					continue;
				}

				const_name = php_com_olestring_to_string(bstr_ids, &len, codepage TSRMLS_CC);
				c.name = STR_INIT(const_name, len, 1);
				// TODO: avoid reallocation???
				efree(const_name);
				if(c.name == NULL) {
					ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
					continue;
				}
//???				c.name_len++; /* include NUL */
				SysFreeString(bstr_ids);

				/* sanity check for the case where the constant is already defined */
				if ((exists = zend_get_constant(c.name TSRMLS_CC)) != NULL) {
					if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, exists TSRMLS_CC)) {
						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name);
					}
					STR_RELEASE(c.name);
					ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
					continue;
				}

				/* register the constant */
				php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage TSRMLS_CC);
				if (Z_TYPE(value) == IS_INT) {
					c.flags = mode;
					ZVAL_INT(&c.value, Z_IVAL(value));
					c.module_number = 0;
					zend_register_constant(&c TSRMLS_CC);
				}
				ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
			}
			ITypeInfo_Release(TypeInfo);
		}
	}
	return SUCCESS;
}
Exemplo n.º 9
0
// クイックソートの実行
void chelp_qsort(void *base, UINT num, UINT width, int (*compare_function)(const void *, const void *))
{
	UCHAR *low;
	UCHAR *high;
	UCHAR *middle;
	UCHAR *low2;
	UCHAR *high2;
	UINT size;
	UCHAR *low_stack[CHELP_QSORT_STACKSIZE], *high_stack[CHELP_QSORT_STACKSIZE];
	int stack_pointer = 0;

	if (num <= 1)
	{
		return;
	}

	low = (UCHAR *)base;
	high = (UCHAR *)base + width * (num - 1);

LABEL_RECURSE:

	size = (UINT)(high - low) / width + 1;

	middle = low + (size / 2) * width;

	if (compare_function(low, middle) > 0)
	{
		chelp_swap(low, middle, width);
	}

	if (compare_function(low, high) > 0)
	{
		chelp_swap(low, high, width);
	}

	if (compare_function(middle, high) > 0)
	{
		chelp_swap(middle, high, width);
	}

	low2 = low;
	high2 = high;

	while (true)
	{
		if (middle > low2)
		{
			do
			{
				low2 += width;
			}
			while (low2 < middle && compare_function(low2, middle) <= 0);
		}

		if (middle <= low2)
		{
			do
			{
				low2 += width;
			}
			while (low2 <= high && compare_function(low2, middle) <= 0);
		}

		do
		{
			high2 -= width;
		}
		while (high2 > middle && compare_function(high2, middle) > 0);

		if (high2 < low2)
		{
			break;
		}

		chelp_swap(low2, high2, width);

		if (middle == high2)
		{
			middle = low2;
		}
	}

	high2 += width;

	if (middle < high2)
	{
		do
		{
			high2 -= width;
		}
		while (high2 > middle && compare_function(high2, middle) == 0);
	}

	if (middle >= high2)
	{
		do
		{
			high2 -= width;
		}
		while (high2 > low && compare_function(high2, middle) == 0);
	}

	if ((high2 - low) >= (high - low2))
	{
		if (low < high2)
		{
			low_stack[stack_pointer] = low;
			high_stack[stack_pointer] = high2;
			stack_pointer++;
		}

		if (low2 < high)
		{
			low = low2;
			goto LABEL_RECURSE;
		}
	}
	else
	{
		if (low2 < high)
		{
			low_stack[stack_pointer] = low2;
			high_stack[stack_pointer] = high;
			stack_pointer++;
		}

		if (low < high2)
		{
			high = high2;
			goto LABEL_RECURSE;
		}
	}

	stack_pointer--;
	if (stack_pointer >= 0)
	{
		low = low_stack[stack_pointer];
		high = high_stack[stack_pointer];

		goto LABEL_RECURSE;
	}
}
Exemplo n.º 10
0
void filesort_heapsort(void **datap,size_t nitems,int(*compare_function)(const void*, const void*))
{
 void **datap1=&datap[-1];
 size_t item;

 /* Fill the heap by pretending to insert the data that is already there */

 for(item=2;item<=nitems;item++)
   {
    size_t index=item;

    /* Bubble up the new value (upside-down, put largest at top) */

    while(index>1)
      {
       int newindex;
       void *temp;

       newindex=index/2;

       if(compare_function(datap1[index],datap1[newindex])<=0) /* reversed comparison to filesort_fixed() above */
          break;

       temp=datap1[index];
       datap1[index]=datap1[newindex];
       datap1[newindex]=temp;

       index=newindex;
      }
   }

 /* Repeatedly pull out the root of the heap and swap with the bottom item */

 for(item=nitems;item>1;item--)
   {
    size_t index=1;
    void *temp;

    temp=datap1[index];
    datap1[index]=datap1[item];
    datap1[item]=temp;

    /* Bubble down the new value (upside-down, put largest at top) */

    while((2*index)<(item-1))
      {
       int newindex;
       void *temp;

       newindex=2*index;

       if(compare_function(datap1[newindex],datap1[newindex+1])<=0) /* reversed comparison to filesort_fixed() above */
          newindex=newindex+1;

       if(compare_function(datap1[index],datap1[newindex])>=0) /* reversed comparison to filesort_fixed() above */
          break;

       temp=datap1[newindex];
       datap1[newindex]=datap1[index];
       datap1[index]=temp;

       index=newindex;
      }

    if((2*index)==(item-1))
      {
       int newindex;
       void *temp;

       newindex=2*index;

       if(compare_function(datap1[index],datap1[newindex])>=0) /* reversed comparison to filesort_fixed() above */
          ; /* break */
       else
         {
          temp=datap1[newindex];
          datap1[newindex]=datap1[index];
          datap1[index]=temp;
         }
      }
   }
}
Exemplo n.º 11
0
index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_t),
                                           int (*compare_function)(const void*,const void*),
                                           int (*post_sort_function)(void*,index_t))
{
 int *fds=NULL,*heap=NULL;
 int nfiles=0,ndata=0;
 index_t count_out=0,count_in=0,total=0;
 size_t datasize=option_filesort_ramsize/option_filesort_threads;
 FILESORT_VARINT nextitemsize,largestitemsize=0;
 void *data,**datap;
 thread_data *threads;
 size_t item;
 int i,more=1;
#if defined(USE_PTHREADS) && USE_PTHREADS
 int nthreads=0;
#endif

 /* Allocate the RAM buffer and other bits */

 threads=(thread_data*)malloc(option_filesort_threads*sizeof(thread_data));

 for(i=0;i<option_filesort_threads;i++)
   {
    threads[i].running=0;

    threads[i].data=malloc(datasize);
    threads[i].datap=NULL;

    threads[i].filename=(char*)malloc(strlen(option_tmpdirname)+24);

    threads[i].compare=compare_function;
   }

 /* Loop around, fill the buffer, sort the data and write a temporary file */

 if(ReadFileBuffered(fd_in,&nextitemsize,FILESORT_VARSIZE))    /* Always have the next item size known in advance */
    goto tidy_and_exit;

 do
   {
    size_t ramused=FILESORT_VARALIGN-FILESORT_VARSIZE;
    int thread=0;

#if defined(USE_PTHREADS) && USE_PTHREADS

    if(option_filesort_threads>1)
      {
       /* Find a spare slot (one *must* be unused at all times) */

       pthread_mutex_lock(&running_mutex);

       for(thread=0;thread<option_filesort_threads;thread++)
          if(!threads[thread].running)
             break;

       pthread_mutex_unlock(&running_mutex);
      }

#endif

    threads[thread].datap=threads[thread].data+datasize;

    threads[thread].n=0;

    /* Read in the data and create pointers */

    while((ramused+FILESORT_VARSIZE+nextitemsize)<=(unsigned)((void*)threads[thread].datap-sizeof(void*)-threads[thread].data))
      {
       FILESORT_VARINT itemsize=nextitemsize;

       *(FILESORT_VARINT*)(threads[thread].data+ramused)=itemsize;

       ramused+=FILESORT_VARSIZE;

       ReadFileBuffered(fd_in,threads[thread].data+ramused,itemsize);

       if(!pre_sort_function || pre_sort_function(threads[thread].data+ramused,count_in))
         {
          *--threads[thread].datap=threads[thread].data+ramused; /* points to real data */

          if(itemsize>largestitemsize)
             largestitemsize=itemsize;

          ramused+=itemsize;

          ramused =FILESORT_VARALIGN*((ramused+FILESORT_VARSIZE-1)/FILESORT_VARALIGN);
          ramused+=FILESORT_VARALIGN-FILESORT_VARSIZE;

          total++;
          threads[thread].n++;
         }
       else
          ramused-=FILESORT_VARSIZE;

       count_in++;

       if(ReadFileBuffered(fd_in,&nextitemsize,FILESORT_VARSIZE))
         {
          more=0;
          break;
         }
      }

    /* No new data read in this time round */

    if(threads[thread].n==0)
       break;

    /* Sort the data pointers using a heap sort (potentially in a thread) */

    if(more==0 && nfiles==0)
       threads[thread].filename[0]=0;
    else
       sprintf(threads[thread].filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles);

#if defined(USE_PTHREADS) && USE_PTHREADS

    /* Shortcut if only one file, don't write to disk */

    if(more==0 && nfiles==0)
       filesort_heapsort(threads[thread].datap,threads[thread].n,threads[thread].compare);
    else if(option_filesort_threads>1)
      {
       pthread_mutex_lock(&running_mutex);

       while(nthreads==(option_filesort_threads-1))
         {
          for(i=0;i<option_filesort_threads;i++)
             if(threads[i].running==2)
               {
                pthread_join(threads[i].thread,NULL);
                threads[i].running=0;
                nthreads--;
               }

          if(nthreads==(option_filesort_threads-1))
             pthread_cond_wait(&running_cond,&running_mutex);
         }

       threads[thread].running=1;

       pthread_mutex_unlock(&running_mutex);

       pthread_create(&threads[thread].thread,NULL,(void* (*)(void*))filesort_vary_heapsort_thread,&threads[thread]);

       nthreads++;
      }
    else
       filesort_vary_heapsort_thread(&threads[thread]);

#else

    /* Shortcut if only one file, don't write to disk */

    if(more==0 && nfiles==0)
       filesort_heapsort(threads[thread].datap,threads[thread].n,threads[thread].compare);
    else
       filesort_vary_heapsort_thread(&threads[thread]);

#endif

    nfiles++;
   }
 while(more);

 /* Wait for all of the threads to finish */

#if defined(USE_PTHREADS) && USE_PTHREADS

 while(option_filesort_threads>1 && nthreads)
   {
    pthread_mutex_lock(&running_mutex);

    pthread_cond_wait(&running_cond,&running_mutex);

    for(i=0;i<option_filesort_threads;i++)
       if(threads[i].running==2)
         {
          pthread_join(threads[i].thread,NULL);
          threads[i].running=0;
          nthreads--;
         }

    pthread_mutex_unlock(&running_mutex);
   }

#endif

 /* Shortcut if only one file, lucky for us we still have the data in RAM) */

 if(nfiles==1)
   {
    for(item=0;item<threads[0].n;item++)
      {
       if(!post_sort_function || post_sort_function(threads[0].datap[item],count_out))
         {
          FILESORT_VARINT itemsize=*(FILESORT_VARINT*)(threads[0].datap[item]-FILESORT_VARSIZE);

          WriteFileBuffered(fd_out,threads[0].datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
          count_out++;
         }
      }

    DeleteFile(threads[0].filename);

    goto tidy_and_exit;
   }

 /* Check that number of files is less than file size */

 largestitemsize=FILESORT_VARALIGN*(1+(largestitemsize+FILESORT_VARALIGN-FILESORT_VARSIZE)/FILESORT_VARALIGN);

 logassert((unsigned)nfiles<((datasize-nfiles*sizeof(void*))/largestitemsize),"Too many temporary files (use more sorting memory?)");

 /* Open all of the temporary files */

 fds=(int*)malloc(nfiles*sizeof(int));

 for(i=0;i<nfiles;i++)
   {
    char *filename=threads[0].filename;

    sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,i);

    fds[i]=ReOpenFileBuffered(filename);

    DeleteFile(filename);
   }

 /* Perform an n-way merge using a binary heap */

 heap=(int*)malloc((1+nfiles)*sizeof(int));

 data=threads[0].data;
 datap=data+datasize-nfiles*sizeof(void*);

 /* Fill the heap to start with */

 for(i=0;i<nfiles;i++)
   {
    int index;
    FILESORT_VARINT itemsize;

    datap[i]=data+FILESORT_VARALIGN-FILESORT_VARSIZE+i*largestitemsize;

    ReadFileBuffered(fds[i],&itemsize,FILESORT_VARSIZE);

    *(FILESORT_VARINT*)(datap[i]-FILESORT_VARSIZE)=itemsize;

    ReadFileBuffered(fds[i],datap[i],itemsize);

    index=i+1;

    heap[index]=i;

    /* Bubble up the new value */

    while(index>1)
      {
       int newindex;
       int temp;

       newindex=index/2;

       if(compare_function(datap[heap[index]],datap[heap[newindex]])>=0)
          break;

       temp=heap[index];
       heap[index]=heap[newindex];
       heap[newindex]=temp;

       index=newindex;
      }
   }

 /* Repeatedly pull out the root of the heap and refill from the same file */

 ndata=nfiles;

 do
   {
    int index=1;
    FILESORT_VARINT itemsize;

    if(!post_sort_function || post_sort_function(datap[heap[index]],count_out))
      {
       itemsize=*(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE);

       WriteFileBuffered(fd_out,datap[heap[index]]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE);
       count_out++;
      }

    if(ReadFileBuffered(fds[heap[index]],&itemsize,FILESORT_VARSIZE))
      {
       heap[index]=heap[ndata];
       ndata--;
      }
    else
      {
       *(FILESORT_VARINT*)(datap[heap[index]]-FILESORT_VARSIZE)=itemsize;

       ReadFileBuffered(fds[heap[index]],datap[heap[index]],itemsize);
      }

    /* Bubble down the new value */

    while((2*index)<ndata)
      {
       int newindex;
       int temp;

       newindex=2*index;

       if(compare_function(datap[heap[newindex]],datap[heap[newindex+1]])>=0)
          newindex=newindex+1;

       if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0)
          break;

       temp=heap[newindex];
       heap[newindex]=heap[index];
       heap[index]=temp;

       index=newindex;
      }

    if((2*index)==ndata)
      {
       int newindex;
       int temp;

       newindex=2*index;

       if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0)
          ; /* break */
       else
         {
          temp=heap[newindex];
          heap[newindex]=heap[index];
          heap[index]=temp;
         }
      }
   }
 while(ndata>0);

 /* Tidy up */

 tidy_and_exit:

 if(fds)
   {
    for(i=0;i<nfiles;i++)
       CloseFileBuffered(fds[i]);
    free(fds);
   }

 if(heap)
    free(heap);

 for(i=0;i<option_filesort_threads;i++)
   {
    free(threads[i].data);

    free(threads[i].filename);
   }

 free(threads);

 return(count_out);
}