Changeset 4cdbcdb30a697d3227b7be9d7deed71656552d22

Show
Ignore:
Timestamp:
03/13/08 19:33:15 (6 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1205436795 +0000
git-parent:

[6afd275c557e7fd4812458abdbe3013685ae7bd7]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1205436795 +0000
Message:

partial match works. apply command works, needs range expansion which I'll lean on pcre for. Didn't have pcre on the plain -- so here we are.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/noit_conf_checks.c

    r7075a66 r4cdbcdb  
    2424 
    2525static void register_console_config_commands(); 
    26  
     26static int noit_console_config_cd(noit_console_closure_t ncct, 
     27                                  int argc, char **argv, 
     28                                  noit_console_state_t *state, void *closure); 
     29 
     30static struct _valid_attr_t { 
     31  const char *scope; 
     32  const char *name; 
     33  const char *xpath; 
     34  int checks_fixate; 
     35} valid_attrs[] = { 
     36  { "/checks", "name", "@name", 0 }, 
     37  { "/checks", "target", "@target", 0 }, 
     38  { "/checks", "period", "@period", 0 }, 
     39  { "/checks", "timeout", "@timeout", 0 }, 
     40  { "/checks", "oncheck", "@oncheck", 0 }, 
     41  { "/checks", "disable", "@disable", 0 }, 
     42  { "/checks", "module", "@module", 1 }, 
     43}; 
     44 
     45void 
     46noit_console_state_add_check_attrs(noit_console_state_t *state, 
     47                                   console_cmd_func_t f) { 
     48  int i; 
     49  for(i = 0; 
     50      i < sizeof(valid_attrs)/sizeof(valid_attrs[0]); 
     51      i++) { 
     52    noit_console_state_add_cmd(state, 
     53      NCSCMD(valid_attrs[i].name, f, 
     54             NULL, &valid_attrs[i])); 
     55  } 
     56
     57static noit_hash_table check_attrs = NOIT_HASH_EMPTY; 
    2758void noit_conf_checks_init(const char *toplevel) { 
     59  int i; 
     60  for(i=0;i<sizeof(valid_attrs)/sizeof(*valid_attrs);i++) { 
     61    noit_hash_store(&check_attrs, 
     62                    valid_attrs[i].name, strlen(valid_attrs[i].name), 
     63                    &valid_attrs[i]); 
     64  } 
    2865  register_console_config_commands(); 
    2966} 
     
    115152} 
    116153static int 
    117 noit_conf_mkcheck_under(const char *ppath, uuid_t out) { 
    118   int rv = -1; 
     154noit_conf_mkcheck_under(const char *ppath, int argc, char **argv, uuid_t out) { 
     155  int i, error = 0, rv = -1; 
    119156  const char *path; 
    120157  char xpath[1024]; 
     
    122159  xmlXPathObjectPtr pobj = NULL; 
    123160  xmlNodePtr node = NULL, newnode; 
     161 
     162  /* attr val [or] no attr (sets of two) */ 
     163  if(argc % 2) goto out; 
    124164 
    125165  noit_conf_xml_xpath(NULL, &xpath_ctxt); 
     
    138178    xmlSetProp(newnode, (xmlChar *)"uuid", (xmlChar *)outstr); 
    139179    xmlSetProp(newnode, (xmlChar *)"disable", (xmlChar *)"true"); 
    140     rv = 0; 
     180 
     181    /* No risk of running off the end (we checked this above) */ 
     182    for(i=0; i<argc; i+=2) { 
     183      struct _valid_attr_t *attrinfo; 
     184      char *attr = argv[i], *val = NULL; 
     185      if(!strcasecmp(argv[i], "no")) attr = argv[i+1]; 
     186      else val = argv[i+1]; 
     187      if(!noit_hash_retrieve(&check_attrs, attr, strlen(attr), 
     188                             (void **)&attrinfo)) { 
     189        error = 1; 
     190        break; 
     191      } 
     192      /* The fixation stuff doesn't matter here, this check is brand-new */ 
     193      xmlUnsetProp(newnode, (xmlChar *)attrinfo->name); 
     194      if(val) 
     195        xmlSetProp(newnode, (xmlChar *)attrinfo->name, (xmlChar *)val); 
     196    } 
     197    if(error) { 
     198      /* Something went wrong, remove the node */ 
     199      xmlUnlinkNode(newnode); 
     200    } 
     201    else 
     202      rv = 0; 
    141203  } 
    142204 out: 
     
    158220  noit_conf_boolean creating_new = noit_false; 
    159221 
     222  if(closure) { 
     223    char *fake_argv[1] = { ".." }; 
     224    noit_console_state_pop(ncct, 0, argv, NULL, NULL); 
     225    noit_console_config_cd(ncct, 1, fake_argv, NULL, NULL); 
     226  } 
     227 
    160228  noit_conf_xml_xpath(NULL, &xpath_ctxt); 
    161   if(argc > 1) { 
    162     nc_printf(ncct, "requires zero or one arguments\n"); 
     229  if(argc < 1) { 
     230    nc_printf(ncct, "requires at least one argument\n"); 
    163231    return -1; 
    164232  } 
    165233 
    166234  info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 
    167   wanted = argc ? argv[0] : NULL; 
     235  wanted = argc == 1 ? argv[0] : NULL; 
    168236  if(!wanted) { 
    169237    /* We are creating a new node */ 
    170238    uuid_t out; 
    171239    creating_new = noit_true; 
    172     if(noit_conf_mkcheck_under(info->path, out)) { 
     240    if(noit_conf_mkcheck_under(info->path, argc, argv, out)) { 
    173241      nc_printf(ncct, "Error creating new check\n"); 
    174242      return -1; 
     
    207275    uuid_copy(info->current_check, checkid); 
    208276    if(creating_new) refresh_subchecks(ncct, info); 
    209     noit_console_state_push_state(ncct, state); 
    210     noit_console_state_init(ncct); 
     277    if(state) { 
     278      noit_console_state_push_state(ncct, state); 
     279      noit_console_state_init(ncct); 
     280    } 
    211281    goto out; 
    212282  } 
     
    428498  } 
    429499  if(!delete && !xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 
     500    if(xmlXPathNodeSetGetLength(pobj->nodesetval) == 1) { 
     501      node = xmlXPathNodeSetItem(pobj->nodesetval, 0); 
     502      if(info->path) free(info->path); 
     503      info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit")); 
     504      goto cdout; 
     505    } 
    430506    err = "cannot create section"; 
    431507    goto bad; 
     
    451527  } 
    452528  node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); 
    453   if((newnode = xmlNewChild(node, NULL, (xmlChar *)argv[0], NULL)) != NULL) 
     529  if((newnode = xmlNewChild(node, NULL, (xmlChar *)argv[0], NULL)) != NULL) { 
     530    if(info->path) free(info->path); 
    454531    info->path = strdup((char *)xmlGetNodePath(newnode) + strlen("/noit")); 
     532  } 
    455533  else { 
    456534    err = "failed to create section"; 
    457535    goto bad; 
    458536  } 
     537 cdout: 
    459538  if(pobj) xmlXPathFreeObject(pobj); 
    460539  return 0; 
     
    523602 bad: 
    524603  if(pobj) xmlXPathFreeObject(pobj); 
    525   nc_printf(ncct, "%s\n", err); 
     604  nc_printf(ncct, "%s [%s]\n", err, xpath); 
    526605  return -1; 
    527606} 
     
    714793  return 0; 
    715794} 
    716 static struct _valid_attr_t { 
    717   const char *scope; 
    718   const char *name; 
    719   const char *xpath; 
    720   int checks_fixate; 
    721 } valid_attrs[] = { 
    722   { "/checks", "name", "@name", 0 }, 
    723   { "/checks", "target", "@target", 0 }, 
    724   { "/checks", "period", "@period", 0 }, 
    725   { "/checks", "timeout", "@timeout", 0 }, 
    726   { "/checks", "oncheck", "@oncheck", 0 }, 
    727   { "/checks", "disable", "@disable", 0 }, 
    728   { "/checks", "module", "@module", 1 }, 
    729 }; 
    730  
    731 void 
    732 noit_console_state_add_check_attrs(noit_console_state_t *state, 
    733                                    console_cmd_func_t f) { 
    734   int i; 
    735   for(i = 0; 
    736       i < sizeof(valid_attrs)/sizeof(valid_attrs[0]); 
    737       i++) { 
    738     noit_console_state_add_cmd(state, 
    739       NCSCMD(valid_attrs[i].name, f, 
    740              NULL, &valid_attrs[i])); 
    741   } 
    742 } 
    743795 
    744796static int 
     
    887939} 
    888940 
    889 #define NEW_STATE(a) (a) = calloc(1, sizeof(*(a))
     941#define NEW_STATE(a) (a) = noit_console_state_alloc(
    890942#define ADD_CMD(a,cmd,func,ss,c) \ 
    891943  noit_console_state_add_cmd((a), \ 
     
    930982  ADD_CMD(_conf_t_check_state, "status", noit_console_show_check, NULL, NULL); 
    931983  ADD_CMD(_conf_t_check_state, "exit", noit_console_config_cd, NULL, ".."); 
     984  ADD_CMD(_conf_t_check_state, "check", noit_console_check, _conf_t_check_state, ".."); 
    932985 
    933986  NEW_STATE(_conf_t_state);  
  • src/noit_console.h

    rb7ec807 r4cdbcdb  
    1212#include "noit_console_telnet.h" 
    1313#include "utils/noit_hash.h" 
     14#include "utils/noit_skiplist.h" 
    1415#include <stdarg.h> 
    1516 
     
    5051typedef struct _console_state { 
    5152  console_prompt_func_t      console_prompt_function; 
    52   noit_hash_table            cmds; 
     53  /*noit_hash_table            cmds; */ 
     54  noit_skiplist              cmds; 
    5355  state_free_func_t          statefree; 
    5456} noit_console_state_t; 
     
    134136  noit_console_state_initial(); 
    135137 
     138API_EXPORT(noit_console_state_t *) 
     139  noit_console_state_alloc(void); 
     140 
    136141API_EXPORT(void) 
    137142  noit_console_state_free(noit_console_state_t *st); 
  • src/noit_console_state.c

    rabfe586 r4cdbcdb  
    2323} 
    2424 
     25static char * 
     26apply_replace(const char *src, const char *name, const char *value) { 
     27  char *result, *cp; 
     28  const char *nextpat, *searchstart; 
     29  char pat[256]; 
     30  int maxlen, patlen, vlen, slen; 
     31  snprintf(pat, sizeof(pat), "{%s}", name); 
     32  patlen = strlen(pat); 
     33  vlen = strlen(value); 
     34  slen = strlen(src); 
     35  /* Worst case is just a stream of replacements. */ 
     36  maxlen = (slen / patlen) * vlen + (slen % patlen) + 1; 
     37  cp = result = malloc(maxlen); 
     38  searchstart = src; 
     39  while((nextpat = strstr(searchstart, pat)) != NULL) { 
     40    memcpy(cp, searchstart, nextpat - searchstart); /* pull the prefix */ 
     41    cp += nextpat - searchstart;                    /* advance destination */ 
     42    memcpy(cp, value, vlen);                        /* copy replacement */ 
     43    cp += vlen;                                     /* advance destination */ 
     44    searchstart += patlen;                          /* set new searchstart */ 
     45  } 
     46  /* Pick up the trailer (plus '\0') */ 
     47  memcpy(cp, searchstart, strlen(searchstart)+1); 
     48  return result; 
     49} 
     50static int 
     51expand_range(const char *range, char ***set) { 
     52  int count; 
     53  /* (full:)?(\d+).(\d+)\.(\d+)(?:\.(\d+))?(?:/(\d+))? */ 
     54  /* (\d+)(?:,(\d+))?\.\.(\d+) */ 
     55/* FIXME: TEST! */ 
     56  *set = malloc(10 * sizeof(*set)); 
     57  for(count=0;count<10;count++) { 
     58    (*set)[count] = strdup("00-test-expand"); 
     59    snprintf((*set)[count], 3, "%02d", count); 
     60    (*set)[count][2] = '-'; 
     61  } 
     62 
     63  return count; 
     64} 
     65int 
     66noit_console_generic_apply(noit_console_closure_t ncct, 
     67                           int argc, char **argv, 
     68                           noit_console_state_t *dstate, 
     69                           void *closure) { 
     70  int i, j, count; 
     71  char *name, *range; 
     72  char **nargv, **expanded; 
     73  int problems = 0; 
     74  if(argc < 3) { 
     75    nc_printf(ncct, "apply <name> <range> cmd ...\n"); 
     76    return -1; 
     77  } 
     78  name = argv[0]; 
     79  range = argv[1]; 
     80  argc -= 2; 
     81  argv += 2; 
     82 
     83  count = expand_range(range, &expanded); 
     84  if(!count) { 
     85    nc_printf(ncct, "apply error: '%s' range produced nothing\n", range); 
     86    return -1; 
     87  } 
     88  if(count < 0) { 
     89    nc_printf(ncct, "apply error: '%s' range would produce %d items.\n", 
     90              range, count); 
     91    return -1; 
     92  } 
     93  nargv = malloc(argc * sizeof(*nargv)); 
     94  for(i=0; i<count; i++) { 
     95    for(j=0; j<argc; j++) nargv[j] = apply_replace(argv[j], name, expanded[i]); 
     96    if(noit_console_state_do(ncct, argc, nargv)) problems = -1; 
     97    for(j=0; j<argc; j++) free(nargv[j]); 
     98    free(expanded[i]); 
     99  } 
     100  free(nargv); 
     101  free(expanded); 
     102  return problems; 
     103} 
     104 
    25105int 
    26106noit_console_state_delegate(noit_console_closure_t ncct, 
     
    47127                       noit_console_state_stack_t *stack, 
    48128                       int argc, char **argv) { 
     129  noit_skiplist_node *next, *amb = NULL; 
    49130  cmd_info_t *cmd; 
    50131 
     
    53134    return -1; 
    54135  } 
    55   if(!noit_hash_retrieve(&stack->state->cmds, 
    56                          argv[0], strlen(argv[0]), (void **)&cmd)) { 
    57     nc_printf(ncct, "No such command: '%s'\n", argv[0]); 
    58     return -1; 
     136  cmd = noit_skiplist_find_neighbors(&stack->state->cmds, argv[0], 
     137                                     NULL, NULL, &next); 
     138  if(!cmd) { 
     139    int ambiguous = 0; 
     140    if(next) { 
     141      cmd_info_t *pcmd = NULL; 
     142      cmd = next->data; 
     143      amb = next; 
     144      noit_skiplist_next(&stack->state->cmds, &amb); 
     145      if(amb) pcmd = amb->data; 
     146      /* So cmd is the next in line... pcmd is the one after that. 
     147       * If they both strncasecmp to 0, we're ambiguous, 
     148       *    neither, then we're not found. 
     149       *    only cmd, then we've found a partial, unambiguous. 
     150       */ 
     151      if(strncasecmp(cmd->name, argv[0], strlen(argv[0])) == 0) { 
     152        if(pcmd && strncasecmp(pcmd->name, argv[0], strlen(argv[0])) == 0) { 
     153          cmd = NULL; 
     154          ambiguous = 1; 
     155        } 
     156      } 
     157      else 
     158        cmd = NULL; 
     159    } 
     160    if(!cmd) { 
     161      if(ambiguous) { 
     162        nc_printf(ncct, "Ambiguous command: '%s'\n", argv[0]); 
     163        amb = next; 
     164        for(amb = next; amb; noit_skiplist_next(&stack->state->cmds, &amb)) { 
     165          cmd = amb->data; 
     166          if(strncasecmp(cmd->name, argv[0], strlen(argv[0])) == 0) 
     167            nc_printf(ncct, "\t%s\n", cmd->name); 
     168          else 
     169            break; 
     170        } 
     171      } 
     172      else 
     173        nc_printf(ncct, "No such command: '%s'\n", argv[0]); 
     174      return -1; 
     175    } 
    59176  } 
    60177  return cmd->func(ncct, argc-1, argv+1, cmd->dstate, cmd->closure); 
     
    65182} 
    66183 
    67 int cmd_info_comparek(void *akv, void *bv) { 
     184int cmd_info_comparek(const void *akv, const void *bv) { 
    68185  char *ak = (char *)akv; 
    69186  cmd_info_t *b = (cmd_info_t *)bv; 
    70187  return strcasecmp(ak, b->name); 
    71188} 
    72 int cmd_info_compare(void *av, void *bv) { 
     189int cmd_info_compare(const void *av, const void *bv) { 
    73190  cmd_info_t *a = (cmd_info_t *)av; 
    74191  cmd_info_t *b = (cmd_info_t *)bv; 
     
    76193} 
    77194 
     195noit_console_state_t * 
     196noit_console_state_alloc(void) { 
     197  noit_console_state_t *s; 
     198  s = calloc(1, sizeof(*s)); 
     199  noit_skiplist_init(&s->cmds); 
     200  noit_skiplist_set_compare(&s->cmds, cmd_info_compare, cmd_info_comparek); 
     201  noit_console_state_add_cmd(s, 
     202      NCSCMD("apply", noit_console_generic_apply, NULL, NULL)); 
     203  return s; 
     204} 
     205 
    78206int 
    79207noit_console_state_add_cmd(noit_console_state_t *state, 
    80208                           cmd_info_t *cmd) { 
    81   return noit_hash_store(&state->cmds, cmd->name, strlen(cmd->name), cmd); 
     209  return (noit_skiplist_insert(&state->cmds, cmd) != NULL); 
    82210} 
    83211 
     
    85213noit_console_state_get_cmd(noit_console_state_t *state, 
    86214                           const char *name) { 
    87   cmd_info_t *cmd = NULL; 
    88   if(noit_hash_retrieve(&state->cmds, name, strlen(name), (void **)&cmd)) 
    89     return cmd; 
    90   return NULL; 
     215  cmd_info_t *cmd; 
     216  cmd = noit_skiplist_find(&state->cmds, name, NULL); 
     217  return cmd; 
    91218} 
    92219 
     
    95222                         state_free_func_t sfreef) { 
    96223  noit_console_state_t *state; 
    97   state = calloc(1, sizeof(*state)); 
     224  state = noit_console_state_alloc(); 
    98225  state->console_prompt_function = promptf; 
    99226  while(*clist) { 
    100     noit_hash_store(&state->cmds, 
    101                     (*clist)->name, strlen((*clist)->name), 
    102                     *clist); 
     227    noit_skiplist_insert(&state->cmds, *clist); 
    103228    clist++; 
    104229  } 
     
    123248  if(!_top_level_state) { 
    124249    static noit_console_state_t *show_state; 
    125     _top_level_state = calloc(1, sizeof(*_top_level_state)); 
     250    _top_level_state = noit_console_state_alloc(); 
    126251    noit_console_state_add_cmd(_top_level_state, &console_command_exit); 
    127     show_state = calloc(1, sizeof(*show_state)); 
     252    show_state = noit_console_state_alloc(); 
    128253    noit_console_state_add_cmd(_top_level_state, 
    129254      NCSCMD("show", noit_console_state_delegate, show_state, NULL)); 
  • src/utils/noit_skiplist.c

    r40c5e31 r4cdbcdb  
    2626#endif 
    2727 
    28 int noit_compare_voidptr(void *a, void *b) { 
     28static int noit_skiplisti_find_compare(noit_skiplist *sl, const void *data, 
     29                                       noit_skiplist_node **ret, 
     30                                       noit_skiplist_node **prev, 
     31                                       noit_skiplist_node **next, 
     32                                       noit_skiplist_comparator_t comp); 
     33 
     34int noit_compare_voidptr(const void *a, const void *b) { 
    2935  if(a < b) return -1; 
    3036  if(a == b) return 0; 
     
    5460} 
    5561 
    56 static int indexing_comp(void *a, void *b) { 
     62static int indexing_comp(const void *a, const void *b) { 
    5763  assert(a); 
    5864  assert(b); 
    5965  return (void *)(((noit_skiplist *)a)->compare)>(void *)(((noit_skiplist *)b)->compare); 
    6066} 
    61 static int indexing_compk(void *a, void *b) { 
     67static int indexing_compk(const void *a, const void *b) { 
    6268  assert(b); 
    6369  return a>(void *)(((noit_skiplist *)b)->compare); 
     
    116122 
    117123void *noit_skiplist_find(noit_skiplist *sl, 
    118               void *data, 
    119               noit_skiplist_node **iter) { 
     124                         const void *data, 
     125                         noit_skiplist_node **iter) { 
     126  return noit_skiplist_find_neighbors(sl, data, iter, NULL, NULL); 
     127
     128void *noit_skiplist_find_neighbors(noit_skiplist *sl, 
     129                                   const void *data, 
     130                                   noit_skiplist_node **iter, 
     131                                   noit_skiplist_node **prev, 
     132                                   noit_skiplist_node **next) { 
    120133  void *ret; 
    121134  noit_skiplist_node *aiter; 
    122135  if(!sl->compare) return 0; 
    123136  if(iter) 
    124     ret = noit_skiplist_find_compare(sl, data, iter, sl->compare); 
     137    ret = noit_skiplist_find_neighbors_compare(sl, data, iter, 
     138                                               prev, next, sl->compare); 
    125139  else 
    126     ret = noit_skiplist_find_compare(sl, data, &aiter, sl->compare); 
     140    ret = noit_skiplist_find_neighbors_compare(sl, data, &aiter, 
     141                                               prev, next, sl->compare); 
    127142  return ret; 
    128 }   
     143
     144 
    129145void *noit_skiplist_find_compare(noit_skiplist *sli, 
    130                       void *data, 
    131                       noit_skiplist_node **iter, 
    132                       noit_skiplist_comparator_t comp) { 
     146                                 const void *data, 
     147                                 noit_skiplist_node **iter, 
     148                                 noit_skiplist_comparator_t comp) { 
     149  return noit_skiplist_find_neighbors_compare(sli, data, iter, 
     150                                              NULL, NULL, comp); 
     151
     152void *noit_skiplist_find_neighbors_compare(noit_skiplist *sli, 
     153                                           const void *data, 
     154                                           noit_skiplist_node **iter, 
     155                                           noit_skiplist_node **prev, 
     156                                           noit_skiplist_node **next, 
     157                                           noit_skiplist_comparator_t comp) { 
    133158  noit_skiplist_node *m = NULL; 
    134159  noit_skiplist *sl; 
     160  if(iter) *iter = NULL; 
     161  if(prev) *prev = NULL; 
     162  if(next) *next = NULL; 
    135163  if(comp==sli->compare || !sli->index) { 
    136164    sl = sli; 
     
    140168    sl= (noit_skiplist *) m->data; 
    141169  } 
    142   noit_skiplisti_find_compare(sl, data, iter, sl->comparek); 
     170  noit_skiplisti_find_compare(sl, data, iter, prev, next, sl->comparek); 
    143171  return (*iter)?((*iter)->data):(*iter); 
    144172} 
    145 int noit_skiplisti_find_compare(noit_skiplist *sl, 
    146                      void *data, 
    147                      noit_skiplist_node **ret, 
    148                      noit_skiplist_comparator_t comp) { 
     173static int noit_skiplisti_find_compare(noit_skiplist *sl, 
     174                                       const void *data, 
     175                                       noit_skiplist_node **ret, 
     176                                       noit_skiplist_node **prev, 
     177                                       noit_skiplist_node **next, 
     178                                       noit_skiplist_comparator_t comp) { 
    149179  noit_skiplist_node *m = NULL; 
    150180  int count=0; 
     181  if(ret) *ret = NULL; 
     182  if(prev) *prev = NULL; 
     183  if(next) *next = NULL; 
    151184  m = sl->top; 
    152185  while(m) { 
    153     int compared = -1; 
    154     if(m->next) compared=comp(data, m->next->data); 
    155     if(compared == 0) { 
    156 #ifdef SL_DEBUG 
    157       printf("Looking -- found in %d steps\n", count); 
    158 #endif 
    159       m=m->next; 
    160       while(m->down) m=m->down; 
     186    int compared; 
     187    compared = (m->next) ? comp(data, m->next->data) : -1; 
     188    if(compared == 0) { /* Found */ 
     189      m=m->next; /* m->next is the match */ 
     190      while(m->down) m=m->down; /* proceed to the bottom-most */ 
    161191      *ret = m; 
     192      if(prev) *prev = m->prev; 
     193      if(next) *next = m->next; 
    162194      return count; 
    163195    } 
    164     if((m->next == NULL) || (compared<0)) 
    165       m = m->down, count++; 
     196    if((m->next == NULL) || (compared<0)) { 
     197      if(m->down == NULL) { 
     198        /* This is... we're about to bail, figure out our neighbors */ 
     199        if(prev) *prev = (m == sl->bottom) ? NULL : m; 
     200        if(next) *next = m->next; 
     201      } 
     202      m = m->down; 
     203      count++; 
     204    } 
    166205    else 
    167206      m = m->next, count++; 
    168207  } 
    169 #ifdef SL_DEBUG 
    170   printf("Looking -- not found in %d steps\n", count); 
    171 #endif 
    172208  *ret = NULL; 
    173209  return count; 
     
    184220} 
    185221noit_skiplist_node *noit_skiplist_insert(noit_skiplist *sl, 
    186                               void *data) { 
     222                                         const void *data) { 
    187223  if(!sl->compare) return 0; 
    188224  return noit_skiplist_insert_compare(sl, data, sl->compare); 
     
    190226 
    191227noit_skiplist_node *noit_skiplist_insert_compare(noit_skiplist *sl, 
    192                                       void *data, 
    193                                       noit_skiplist_comparator_t comp) { 
     228                                                 const void *data, 
     229                                                 noit_skiplist_comparator_t comp) { 
    194230  noit_skiplist_node *m, *p, *tmp, *ret = NULL, **stack; 
    195231  int nh=1, ch, stacki; 
     
    262298    tmp->down = p; 
    263299    if(p) p->up=tmp; 
    264     tmp->data = data; 
     300    tmp->data = (void *)data; 
    265301    tmp->sl = sl; 
    266302    m->next = tmp; 
     
    286322} 
    287323int noit_skiplist_remove(noit_skiplist *sl, 
    288             void *data, noit_freefunc_t myfree) { 
     324                         const void *data, noit_freefunc_t myfree) { 
    289325  if(!sl->compare) return 0; 
    290326  return noit_skiplist_remove_compare(sl, data, myfree, sl->comparek); 
     
    317353} 
    318354int noit_skiplist_remove_compare(noit_skiplist *sli, 
    319                       void *data, 
    320                       noit_freefunc_t myfree, noit_skiplist_comparator_t comp) { 
     355                                 const void *data, 
     356                                 noit_freefunc_t myfree, 
     357                                 noit_skiplist_comparator_t comp) { 
    321358  noit_skiplist_node *m; 
    322359  noit_skiplist *sl; 
     
    328365    sl= (noit_skiplist *) m->data; 
    329366  } 
    330   noit_skiplisti_find_compare(sl, data, &m, comp); 
     367  noit_skiplisti_find_compare(sl, data, &m, NULL, NULL, comp); 
    331368  if(!m) return 0; 
    332369  while(m->previndex) m=m->previndex; 
  • src/utils/noit_skiplist.h

    rb62cf2b r4cdbcdb  
    2727/* This is the function type that must be implemented per object type 
    2828   that is used in a skiplist for comparisons to maintain order */ 
    29 typedef int (*noit_skiplist_comparator_t)(void *, void *); 
     29typedef int (*noit_skiplist_comparator_t)(const void *, const void *); 
    3030typedef void (*noit_freefunc_t)(void *); 
    3131 
     
    6464                             noit_skiplist_comparator_t); 
    6565noit_skiplist_node *noit_skiplist_getlist(noit_skiplist *sl); 
    66 void *noit_skiplist_find_compare(noit_skiplist *sl, void *data, 
     66void *noit_skiplist_find_compare(noit_skiplist *sl, const void *data, 
    6767                                 noit_skiplist_node **iter, 
    6868                                 noit_skiplist_comparator_t func); 
    69 void *noit_skiplist_find(noit_skiplist *sl, void *data, 
     69void *noit_skiplist_find_neighbors_compare(noit_skiplist *sl, const void *data, 
     70                                           noit_skiplist_node **iter, 
     71                                           noit_skiplist_node **prev, 
     72                                           noit_skiplist_node **next, 
     73                                           noit_skiplist_comparator_t func); 
     74void *noit_skiplist_find(noit_skiplist *sl, const void *data, 
    7075                         noit_skiplist_node **iter); 
     76void *noit_skiplist_find_neighbors(noit_skiplist *sl, const void *data, 
     77                                   noit_skiplist_node **iter, 
     78                                   noit_skiplist_node **prev, 
     79                                   noit_skiplist_node **next); 
    7180void *noit_skiplist_next(noit_skiplist *sl, noit_skiplist_node **); 
    7281void *noit_skiplist_previous(noit_skiplist *sl, noit_skiplist_node **); 
    7382 
    7483noit_skiplist_node *noit_skiplist_insert_compare(noit_skiplist *sl, 
    75                                                  void *data, 
     84                                                 const void *data, 
    7685                                                 noit_skiplist_comparator_t comp); 
    77 noit_skiplist_node *noit_skiplist_insert(noit_skiplist *sl, void *data); 
    78 int noit_skiplist_remove_compare(noit_skiplist *sl, void *data, 
     86noit_skiplist_node *noit_skiplist_insert(noit_skiplist *sl, const void *data); 
     87int noit_skiplist_remove_compare(noit_skiplist *sl, const void *data, 
    7988                                 noit_freefunc_t myfree, 
    8089                                 noit_skiplist_comparator_t comp); 
    81 int noit_skiplist_remove(noit_skiplist *sl, void *data, noit_freefunc_t myfree); 
     90int noit_skiplist_remove(noit_skiplist *sl, const void *data, 
     91                         noit_freefunc_t myfree); 
    8292int noit_skiplisti_remove(noit_skiplist *sl, noit_skiplist_node *m, 
    8393                          noit_freefunc_t myfree); 
    8494void noit_skiplist_remove_all(noit_skiplist *sl, noit_freefunc_t myfree); 
    8595 
    86 int noit_skiplisti_find_compare(noit_skiplist *sl, void *data, 
    87                                 noit_skiplist_node **ret, 
    88                                 noit_skiplist_comparator_t comp); 
    89  
    9096void *noit_skiplist_pop(noit_skiplist * a, noit_freefunc_t myfree); 
    9197void *noit_skiplist_peek(noit_skiplist * a); 
    9298 
    93 int noit_compare_voidptr(void *, void *); 
     99int noit_compare_voidptr(const void *, const void *); 
    94100 
    95101#endif