[PD-cvs] externals/zexy/src index.c,1.3,1.4
IOhannes m zmölnig
zmoelnig at users.sourceforge.net
Mon May 30 16:34:46 CEST 2005
- Previous message: [PD-cvs] externals/miXed/toxy pluswidget.c, NONE, 1.1 Makefile.objects, 1.5, 1.6 build_counter, 1.15, 1.16 notes.txt, 1.3, 1.4 plustot.c, 1.4, 1.5 plustot.env.c, 1.2, 1.3 plustot.h, 1.2, 1.3 plustot.in.c, 1.1, 1.2 plustot.out.c, 1.1, 1.2 plustot.print.c, 1.2, 1.3 plustot.qlist.c, 1.3, 1.4 plustot.var.c, 1.1, 1.2
- Next message: [PD-cvs] externals/zexy/examples index.pd,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/externals/zexy/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21097
Modified Files:
index.c
Log Message:
improved performance (i think)
added a lot of new functionality
Index: index.c
===================================================================
RCS file: /cvsroot/pure-data/externals/zexy/src/index.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** index.c 19 May 2005 09:42:55 -0000 1.3
--- index.c 30 May 2005 14:34:44 -0000 1.4
***************
*** 20,31 ****
"index" simulates an associative index :: that is : convert a symbol to an index
! */
! #include "zexy.h"
! #include <string.h>
! #include <stdio.h>
! #define MAXKEYLEN 16
/* ----------------------- index --------------------- */
--- 20,38 ----
"index" simulates an associative index :: that is : convert a symbol to an index
! CAVEATS: starts to count at "1"
! TODO: use "symbol" instead of "char*" : FIXED
! TODO: "dump" the contents (so we can share between [index]es, ...) FIXED
! TODO: "compact": move all entries to the beginning of the array FIXED
! TODO: "sort" FIXED
! TODO: "add" at a specific position (like "add 10 hallo" of "add hallo 10") (??) FIXED
! TODO: "delete" from a specific position (like "delete 4" deletes the 4th element) FIXED
! TODO: get the number of stored entries ("bang") FIXED
!
! TODO: resize the array if it gets to small
! */
! #include "zexy.h"
/* ----------------------- index --------------------- */
***************
*** 39,47 ****
int entries, maxentries;
int auto_mode; /* 1--add if key doesn't already exist; 0--do not add; */
! char **names;
} t_index;
! static int find_last(char **names, int maxentries)
{ /* returns the index of the last entry (0..(maxentries-1)) */
while (maxentries--) if (names[maxentries]) return maxentries;
--- 46,63 ----
int entries, maxentries;
int auto_mode; /* 1--add if key doesn't already exist; 0--do not add; */
+ int auto_resize; /* 1--resize the array if we are running out of slots; 0--don't */
! t_symbol **names;
} t_index;
! /************************************
! * helpers
! */
!
!
! /* find the last non-NULL entry in the array *
! * LATER: shouldn't this return "-1" on failure ?
! */
! static int find_last(t_symbol **names, int maxentries)
{ /* returns the index of the last entry (0..(maxentries-1)) */
while (maxentries--) if (names[maxentries]) return maxentries;
***************
*** 49,53 ****
}
! static int find_item(const char *key, char **names, int maxentries)
{ /* returns index (0..[maxentries-1?]) on success; -1 if the item could not be found */
int i=-1;
--- 65,72 ----
}
! /* search the array for "key"
! * if it is not there, return "-1"
! */
! static int find_item(const t_symbol *key, t_symbol **names, int maxentries)
{ /* returns index (0..[maxentries-1?]) on success; -1 if the item could not be found */
int i=-1;
***************
*** 55,65 ****
while (++i<=max)
! if (names[i])
! if (!strcmp(key, names[i])) return i;
return -1;
}
! static int find_free(char **names, int maxentries)
{
int i=0;
--- 74,86 ----
while (++i<=max)
! if (names[i] && key==names[i]) return i;
return -1;
}
! /* find the first NULL entry in the array
! * return "-1" if none can be found
! */
! static int find_free(t_symbol **names, int maxentries)
{
int i=0;
***************
*** 72,75 ****
--- 93,113 ----
}
+ /************************************
+ * methods
+ */
+ static void index_add(t_index *x, t_symbol *s, t_float f);
+
+ /* look up a symbol in the map */
+ static void index_symbol(t_index *x, t_symbol *s)
+ {
+ int element;
+ if ( (element = find_item(s, x->names, x->maxentries)+1) )
+ outlet_float(x->x_obj.ob_outlet, (t_float)element);
+ else if (x->auto_mode) // not yet stored: add automatically
+ index_add(x, s, 0);
+ else outlet_float(x->x_obj.ob_outlet, 0.f); // not yet stored but do not add
+ }
+
+ /* output the entry at a given index */
static void index_float(t_index *x, t_float findex)
{
***************
*** 78,133 ****
{
/* TB: output symbol to outlet */
! t_symbol * s = gensym (x->names[iindex-1]);
! outlet_symbol (x->x_obj.ob_outlet,s);
! // post("iindex[%d] = %s", iindex, x->names[iindex-1]);
}
}
- static void index_auto(t_index *x, t_float automod)
- {
- x->auto_mode = !(!automod);
- }
-
! static void index_add(t_index *x, t_symbol *s)
{
! int newentry;
int ok = 0;
- if (! (find_item(s->s_name, x->names, x->maxentries)+1) ) {
if ( x->entries < x->maxentries ) {
! newentry=find_free(x->names, x->maxentries);
if (newentry + 1) {
- char *buf = (char *)getbytes(sizeof(char) * MAXKEYLEN);
x->entries++;
! strcpy(buf, s->s_name);
! x->names[newentry]=buf;
!
! ok=1;
outlet_float(x->x_obj.ob_outlet, (t_float)newentry+1);
! } else post("index :: couldn't find any place for new entry");
! } else post("index :: max number of elements (%d) reached !", x->maxentries);
} else post("index :: element already exists");
! if (!ok) outlet_float(x->x_obj.ob_outlet, -1.f);
}
!
! static void index_delete(t_index *x, t_symbol *s)
{
! int element;
! t_float r = -1.f;
! if ( (element = find_item(s->s_name,x->names, x->maxentries))+1 ) {
! freebytes(x->names[element], sizeof(char) * MAXKEYLEN);
! x->names[element]=0;
! r = 0.f;
x->entries--;
! } else post("index :: couldn't find element");
!
! outlet_float(x->x_obj.ob_outlet, r);
}
static void index_reset(t_index *x)
{
--- 116,201 ----
{
/* TB: output symbol to outlet */
! outlet_symbol (x->x_obj.ob_outlet,x->names[iindex-1]);
}
}
! /* add a symbol to the map (if possible) */
! static void index_add(t_index *x, t_symbol *s, t_float f)
{
! int newentry=(int)f;
int ok = 0;
+
+ if (! (find_item(s, x->names, x->maxentries)+1) ) {
+ if (x->auto_resize && x->entries==x->maxentries){
+ /* do some resizing */
+ int maxentries=x->maxentries*2;
+ int i;
+ t_symbol**buf=(t_symbol **)getbytes(sizeof(t_symbol *) * maxentries);
+ if(buf!=0){
+ memcpy(buf, x->names, sizeof(t_symbol *) * x->maxentries);
+ for(i=x->maxentries; i<maxentries; i++)buf[i]=0;
+
+ freebytes(x->names, sizeof(t_symbol *) * x->maxentries);
+
+ x->names=buf;
+ x->maxentries=maxentries;
+ }
+ }
if ( x->entries < x->maxentries ) {
! if(newentry>0){
! newentry--;
! if(x->names[newentry]){ /* it is already taken! */
! error("index :: couldn't add element at position %d (already taken)", newentry+1);
! outlet_float(x->x_obj.ob_outlet, -1.f);
! return;
! }
! } else
! newentry=find_free(x->names, x->maxentries);
!
if (newentry + 1) {
x->entries++;
! x->names[newentry]=s;
outlet_float(x->x_obj.ob_outlet, (t_float)newentry+1);
+ return;
! } else error("index :: couldn't find any place for new entry");
! } else error("index :: max number of elements (%d) reached !", x->maxentries);
} else post("index :: element already exists");
! /* couldn't add the symbol to our index table */
! outlet_float(x->x_obj.ob_outlet, -1.f);
}
! /* delete a symbol from the map (if it is in there) */
! static void index_delete(t_index *x, t_symbol *s, int argc, t_atom*argv)
{
! int index=-1;
! if(argc!=1){
! error("index :: delete what ?");
! return;
! } else {
! if(argv->a_type==A_FLOAT){
! index=atom_getint(argv)-1;
! } else if (argv->a_type==A_SYMBOL){
! index=find_item(atom_getsymbol(argv),x->names, x->maxentries);
! } else {
! error("index :: delete what ?");
! return;
! }
! }
! if ( index >= 0 && index < x->maxentries) {
! x->names[index]=0;
x->entries--;
! outlet_float(x->x_obj.ob_outlet, 0.0);
! } else {
! post("index :: couldn't find element");
! outlet_float(x->x_obj.ob_outlet, -1.0);
! }
}
+ /* delete all symbols from the map */
static void index_reset(t_index *x)
{
***************
*** 136,140 ****
while (i--)
if (x->names[i]) {
- freebytes(x->names[i], sizeof(char) * MAXKEYLEN);
x->names[i]=0;
}
--- 204,207 ----
***************
*** 145,162 ****
}
! static void index_symbol(t_index *x, t_symbol *s)
{
! int element;
! if ( (element = find_item(s->s_name, x->names, x->maxentries)+1) )
! outlet_float(x->x_obj.ob_outlet, (t_float)element);
! else if (x->auto_mode)
! index_add(x, s);
! else outlet_float(x->x_obj.ob_outlet, 0.f);
}
static void *index_new(t_symbol *s, int argc, t_atom *argv)
{
t_index *x = (t_index *)pd_new(index_class);
! char** buf;
int maxentries = 0, automod=0;
--- 212,295 ----
}
! /* output the number of entries stored in the array */
! static void index_bang(t_index *x)
{
! outlet_float(x->x_obj.ob_outlet, (t_float)x->entries);
! }
! /* dump each entry in the format: "list <symbol> <index>" */
! static void index_dump(t_index *x)
! {
! t_atom ap[2];
! int i=0;
!
! for(i=0; i<x->maxentries; i++){
! if(x->names[i]){
! SETSYMBOL(ap, x->names[i]);
! SETFLOAT(ap+1, i+1);
! outlet_list(x->x_obj.ob_outlet, 0, 2, ap);
! }
! }
! }
!
! /* compact all entries, removing all holes in the map */
! static void index_compact(t_index *x){
! int i,j;
! for(i=0; i<x->entries; i++){
! if(!x->names[i]){
! for(j=i+1; j<x->maxentries; j++){
! if(x->names[j]){
! x->names[i]=x->names[j];
! x->names[j]=0;
! break;
! }
! }
! }
! }
! }
! /* sort the map alphabetically */
! static void index_sort(t_index *x){
! int entries=x->entries;
! int step=entries;
! int loops=1, n;
! t_symbol**buf=x->names;
! index_compact(x); /* couldn't we do it more "in-place", e.g. don't touch empty slots ? */
!
! while(step>1){
! //step = (step % 2)?(step+1)/2:step/2;
! step+=step%2;
! step>>=1;
! int i = loops;
! loops+=2;
!
! while(i--) { /* there might be some optimization in here */
! for (n=0; n<(x->entries-step); n++) {
! int comp=strcmp(buf[n]->s_name,buf[n+step]->s_name);
! if (comp>0) { // compare STRINGS not SYMBOLS
! t_symbol*s_tmp = buf[n];
! buf[n] = buf[n+step];
! buf[n+step] = s_tmp;
! }
! }
! }
! }
}
+ /* turn on/off auto-adding of elements that are not yet in the map */
+ static void index_auto(t_index *x, t_float automod)
+ {
+ x->auto_mode = !(!automod);
+ }
+ /* turn on/off auto-resizing of the map if it gets to small */
+ static void index_resize(t_index *x, t_float automod)
+ {
+ x->auto_resize = !(!automod);
+ }
+
+
+
static void *index_new(t_symbol *s, int argc, t_atom *argv)
{
t_index *x = (t_index *)pd_new(index_class);
! t_symbol** buf;
int maxentries = 0, automod=0;
***************
*** 170,177 ****
if (!maxentries) maxentries=128;
! buf = (char **)getbytes(sizeof(char *) * maxentries);
- i = maxentries;
- while (i--) buf[i]=0;
x->entries = 0;
--- 303,308 ----
if (!maxentries) maxentries=128;
! buf = (t_symbol **)getbytes(sizeof(t_symbol *) * maxentries);
x->entries = 0;
***************
*** 179,182 ****
--- 310,316 ----
x->names = buf;
x->auto_mode = !(!automod);
+ x->auto_resize = 1;
+
+ while (maxentries--) buf[maxentries]=0;
outlet_new(&x->x_obj, &s_float);
***************
*** 187,192 ****
static void index_free(t_index *x)
{
! index_reset(x);
! freebytes(x->names, sizeof(char *) * x->maxentries);
}
--- 321,325 ----
static void index_free(t_index *x)
{
! freebytes(x->names, sizeof(t_symbol *) * x->maxentries);
}
***************
*** 195,205 ****
{
post("\n%c index :: index symbols to indices", HEARTSYMBOL);
! post("<symbol>\t : look up the <symbol> in the index and return it's index\n"
! "'add <symbol>'\t: add a new symbol to the index\n"
! "'delete <symbol>' : delete a symbol from the index\n"
! "'reset'\t\t : delete the whole index\n"
! "'auto <1/0>\t : if auto is 1 and a yet unknown symbol is looked up it is\n\t\t\t automatically added to the index\n"
! "'help'\t\t : view this"
! "\noutlet : <n>\t : index of the <symbol>");
post("\ncreation:\"index [<maxelements> [<auto>]]\": creates a <maxelements> sized index");
}
--- 328,347 ----
{
post("\n%c index :: index symbols to indices", HEARTSYMBOL);
! post("<symbol> : look up the <symbol> in the index and return it's index\n"
! "\n<int> : look up the element at index <int> in the index"
! "\n'add <symbol>' : add a new symbol to the index-map"
! "\n'add <symbol> <int>' : add a new symbol at the index <int>"
! "\n'delete <symbol>' : delete a symbol from the index-map"
! "\n'delete <int>' : delete the entry at index <int> from the index-map"
! "\n'reset' : delete the whole index-map"
! "\n'bang' : return the number of entries in the index-map"
! "\n'dump' : dump each entry in the format \"list <symbol> <index>\""
! "\n'compact' : remove holes in the index-map"
! "\n'sort' : alphabetically sort the entries"
! "\n'auto <1/0> : if auto is 1 and a yet unknown symbol is looked up it is\n\t\t\t automatically added to the index-map"
! "\n'resize <1/0> : if resize is 1 (default), the index-map is resized\n\t\t\t automatically if needed"
! "\n'help' : view this"
! "\noutlet : <n> : index of the <symbol>"
! "\n <symbol> : entry at <index>");
post("\ncreation:\"index [<maxelements> [<auto>]]\": creates a <maxelements> sized index");
}
***************
*** 214,223 ****
class_addmethod(index_class, (t_method)index_reset, gensym("reset"), 0);
! class_addmethod(index_class, (t_method)index_delete, gensym("delete"), A_SYMBOL, 0);
! class_addmethod(index_class, (t_method)index_add, gensym("add"), A_SYMBOL, 0);
class_addmethod(index_class, (t_method)index_auto, gensym("auto"), A_FLOAT, 0);
! class_addfloat(index_class, (t_method)index_float);
class_addmethod(index_class, (t_method)helper, gensym("help"), 0);
--- 356,371 ----
class_addmethod(index_class, (t_method)index_reset, gensym("reset"), 0);
! class_addmethod(index_class, (t_method)index_delete, gensym("delete"), A_GIMME, 0);
! // class_addmethod(index_class, (t_method)index_add, gensym("add"), A_SYMBOL, 0);
! class_addmethod(index_class, (t_method)index_add, gensym("add"), A_SYMBOL, A_DEFFLOAT, 0);
class_addmethod(index_class, (t_method)index_auto, gensym("auto"), A_FLOAT, 0);
+ class_addmethod(index_class, (t_method)index_resize, gensym("resize"), A_FLOAT, 0);
! class_addfloat(index_class, (t_method)index_float);
! class_addbang(index_class, (t_method)index_bang);
! class_addmethod(index_class, (t_method)index_sort, gensym("sort"), 0);
! class_addmethod(index_class, (t_method)index_compact, gensym("compact"), 0);
! class_addmethod(index_class, (t_method)index_dump, gensym("dump"), 0);
class_addmethod(index_class, (t_method)helper, gensym("help"), 0);
- Previous message: [PD-cvs] externals/miXed/toxy pluswidget.c, NONE, 1.1 Makefile.objects, 1.5, 1.6 build_counter, 1.15, 1.16 notes.txt, 1.3, 1.4 plustot.c, 1.4, 1.5 plustot.env.c, 1.2, 1.3 plustot.h, 1.2, 1.3 plustot.in.c, 1.1, 1.2 plustot.out.c, 1.1, 1.2 plustot.print.c, 1.2, 1.3 plustot.qlist.c, 1.3, 1.4 plustot.var.c, 1.1, 1.2
- Next message: [PD-cvs] externals/zexy/examples index.pd,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list