420e36764f00196bb39f95419f74788d0a82d5f6
[util-vserver.git] / ensc_vector / vector-searchselforg.c
1 // $Id: vector-searchselforg.c,v 1.1 2005/03/17 14:47:21 ensc Exp $    --*- c -*--
2
3 // Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
8 //  
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //  
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "vector.h"
24 #include "vector-internal.h"
25
26 #include <string.h>
27 #include <assert.h>
28 #include <stdbool.h>
29
30 void *
31 Vector_searchSelfOrg(struct Vector *vec, void const *key,
32                      int (*compare)(const void *, const void *),
33                      VectorSelfOrgMethod method)
34 {
35   char * const  start_ptr = vec->data;
36   char * const  end_ptr   = start_ptr + vec->count*vec->elem_size;
37   char          *ptr      = start_ptr;
38   
39   for (; ptr<end_ptr && compare(ptr, key)!=0; )
40     ptr += vec->elem_size;
41
42   if      (end_ptr  <= ptr) ptr = 0;
43   else if (start_ptr < ptr) {
44     char                tmp[vec->elem_size];
45     memcpy(tmp, ptr, vec->elem_size);
46
47     assert(ptr >= start_ptr+vec->elem_size);
48
49     switch (method) {
50       case vecMOVE_FRONT                :
51         memmove(start_ptr+vec->elem_size, start_ptr, ptr - start_ptr);
52
53         ptr = start_ptr;
54         break;
55         
56       case vecSHIFT_ONCE                :
57         memmove(ptr, ptr  - vec->elem_size, vec->elem_size);
58         ptr -= vec->elem_size;
59         break;
60
61       default           :
62         assert(false);
63         ptr   = 0;
64     }
65
66     memcpy (ptr, tmp, vec->elem_size);
67   }
68
69   return ptr;
70 }
71