Difference between revisions of "ListSpace.c"

From Organic Design wiki
(char must be unsigned for traversing)
m (Nad moved page ListSpace.h to ListSpace.c over redirect)
 
(118 intermediate revisions by 3 users not shown)
Line 1: Line 1:
#define MAXITEMS 10000
+
{{legacy}}
#define ROOT 0
+
<source lang="c">
 +
// [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon
 +
// This article and all its includes are licenced under LGPL
 +
// GPL: [[[[http://www.gnu.org/copyleft/lesser.html]]]]
 +
// SRC: [[[[http://www.organicdesign.co.nz/listSpace.c]]]]
 +
// included in [[[[http://www.organicdesign.co.nz/category:peerd/files/C|peerd]]]][[[[http://www.organicdesign.co.nz/peerd.c|/peerd.c]]]]
 +
 
 
typedef int item;
 
typedef int item;
item items = 0;
+
item *space;
int *space;
+
 
 +
// tmp: should use new pointer-lists
 +
#define MAXITEMS 100000
 +
int items = 0;
 +
char *nssBuf;
 +
 
 +
// Prototypes
 +
int listInit();
 +
int listExit();
 +
item listInsert();
 +
item listRemove(item subject);
 +
item listTraverse(item subject, item object);
 +
item listGetValue(item subject);
 +
item listSetValue(item subject, item value);
 +
void listStats();
 +
item trieGetValue(unsigned char *key);
 +
item trieSetValue(unsigned char *key, item value);
 +
 
  
// Create a new listItem in the space and return its index
+
// ----------------------------------------------------------------------------------------- //
item listInsert() {
+
// listSpace.c
//printf("listInsert(): new item %d\n", items);
 
return items++;
 
}
 
  
// Start at subject listItem and traverse the object as an association to a new listItem
+
int listInit() {
// - object is also a listItem reference and its binary address is used as the traversal path
+
// all these are tmp and should be handled with new pointer-list
// - subject and object (all list-item references are ints starting at item 0)
+
space = calloc(MAXITEMS,3*sizeof(item));
item listTraverse(item subject, item object) {
+
nssBuf = malloc(30);
object += 2; // tmp: can't traverse items 0 or 1
+
return EXIT_SUCCESS;
int i,j;
 
for (i=1; i<=object>>1; i<<=1)
 
subject = space[j=subject*3+(object&i?1:0)]?space[j]:(space[j]=listInsert());
 
return subject;
 
 
}
 
}
  
// Get the value (payload key) of the subject Item
+
int listExit() {
item listGetValue(item subject) {
+
free(space);
return space[subject*3+2];
 
 
}
 
}
  
// Set the payload key of the subject Item to the passed value
+
// Create a new listItem in the space and return its index
void listSetValue(item subject, item value) {
+
item listInsert() {
space[subject*3+2] = value;
+
// Unlink an item from the free-list and return its index
 +
if (items >= MAXITEMS) logAdd("No more items in the space!");
 +
else return items++;
 +
return 0;
 
}
 
}
  
// The following four functions are used internally by trieSet/Get
+
// Move the subject onto the free-list
// - Treat each character in text-keys as a list-item-index to traverse from root
+
item listRemove(item subject) {
// - ListSpace cannot store pointers because they are not binary-traversable, so
 
//  an ordered list of pointers to hash-table data is maintained so that list-space
 
//  can refer to the pointers in the list by integer index
 
 
 
item trieTraverse(unsigned char *text) {
 
item subject = ROOT;
 
int i;
 
for (i=0; i<strlen(text); i++)
 
subject = listTraverse(subject, (item)text[i]);
 
 
return subject;
 
return subject;
 
}
 
}
  
void *trieReturnPointer(int index) {
+
// Start at subject listItem and traverse the key as an association to a new listItem
void *ptr;
+
// - key is also a listItem reference and its binary address is used as the traversal path
return ptr;
+
// - subject and key (all list-item references are ints starting at item 0)
 +
// - if key is 0 the subject is returned unchanged, key 1 and 2 are the two single-iteration traversals
 +
item listTraverse(item subject, item key) {
 +
if (key++) {
 +
int i,j;
 +
for (i=1; i<=key>>1; i<<=1)
 +
subject = space[j=subject+(subject<<1)+(key&i?1:0)]?space[j]:(space[j]=listInsert());
 +
}
 +
return subject;
 
}
 
}
  
int trieInsertPointer(void *ptr) {
+
// Get the value (payload key) of the subject Item
int index;
+
item listGetValue(item subject) {
return index;
+
return space[subject+(subject<<1)+2];
 
}
 
}
  
void trieRemovePointer(int index) {
+
// Set the payload key of the subject Item to the passed value
 +
item listSetValue(item subject, item value) {
 +
return space[subject+(subject<<1)+2] = value;
 
}
 
}
 
// Return the pointer to the pointer-value associated with the passed text-key
 
// usage: pval = *trie("myKey")
 
//        *trie("myKey") = "myValue"
 
void *trie(char* key) {
 
return trieReturnPointer((int)listGetValue(trieTraverse(key)));
 
}
 
 
 
// Allocate memory for maximum ListItems
 
space = calloc(MAXITEMS*3, sizeof(item));
 
printf("%d bytes of memory allocated\n", MAXITEMS*3*sizeof(item));
 
 
// Insert items 0-127 as ascii character nodes
 
// - this allows us to temporarily use list-space as a hash-table
 
//  since C/C++ doesn't inherently have one
 
for (i=0; i<128; i++) listInsert();
 
  
  
 
// Print listSpace statistics
 
// Print listSpace statistics
 
// - currently just counts how many nodes have payloads and displays content
 
// - currently just counts how many nodes have payloads and displays content
void listStatistics() {
+
void listStats() {
 
int i,j,p=0;
 
int i,j,p=0;
 +
printf("\nlistStatistics:\n");
 
for (i=0; i<MAXITEMS; i++) if (listGetValue(i)) p++;
 
for (i=0; i<MAXITEMS; i++) if (listGetValue(i)) p++;
printf("%d items in use:\n", p);
+
printf("\t%d of %d items in use:\n",p,MAXITEMS);
for (i=0; i<MAXITEMS; i++) if (j=listGetValue(i)) printf("    %d = %d\n",i,j);
+
//for (i=0; i<MAXITEMS; i++) if (j=listGetValue(i)) printf("    %d = %d\n",i,j);
 
printf("\n\n");
 
printf("\n\n");
 
}
 
}
 +
 +
 +
// ----------------------------------------------------------------------------------------- //
 +
// Trie
 +
// - not really part of listSpace, but needed by env's with no hash-tables
 +
// - uses ascii traversal by reserving first list items
 +
// - trie sets/gets list items using ascii-traversal
 +
 +
item trieGetValue(unsigned char *key) {
 +
item subject = nodeTRIE;
 +
while(*key) subject = listTraverse(subject,*key++);
 +
return listGetValue(subject);
 +
}
 +
 +
item trieSetValue(unsigned char *key, item value) {
 +
item subject = nodeTRIE;
 +
while(*key) subject = listTraverse(subject,*key++);
 +
return listSetValue(subject,value);
 +
}
 +
</source>
 +
[[Category:C]]

Latest revision as of 13:06, 13 December 2019

Legacy.svg Legacy: This article describes a concept that has been superseded in the course of ongoing development on the Organic Design wiki. Please do not develop this any further or base work on this concept, now this page is for historic record only.
// [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon
// This article and all its includes are licenced under LGPL
// GPL: [[[[http://www.gnu.org/copyleft/lesser.html]]]]
// SRC: [[[[http://www.organicdesign.co.nz/listSpace.c]]]]
// included in [[[[http://www.organicdesign.co.nz/category:peerd/files/C|peerd]]]][[[[http://www.organicdesign.co.nz/peerd.c|/peerd.c]]]]

typedef int item;
item *space;

// tmp: should use new pointer-lists
#define MAXITEMS 100000
int items = 0;
char *nssBuf;

// Prototypes
int listInit();
int listExit();
item listInsert();
item listRemove(item subject);
item listTraverse(item subject, item object);
item listGetValue(item subject);
item listSetValue(item subject, item value);
void listStats();
item trieGetValue(unsigned char *key);
item trieSetValue(unsigned char *key, item value);


// ----------------------------------------------------------------------------------------- //
// listSpace.c

int listInit() {
	// all these are tmp and should be handled with new pointer-list
	space = calloc(MAXITEMS,3*sizeof(item));
	nssBuf = malloc(30);
	return EXIT_SUCCESS;
	}

int listExit() {
	free(space);
	}

// Create a new listItem in the space and return its index
item listInsert() {
	// Unlink an item from the free-list and return its index
	if (items >= MAXITEMS) logAdd("No more items in the space!");
	else return items++;
	return 0;
	}

// Move the subject onto the free-list
item listRemove(item subject) {
	return subject;
	}

// Start at subject listItem and traverse the key as an association to a new listItem
// - key is also a listItem reference and its binary address is used as the traversal path
// - subject and key (all list-item references are ints starting at item 0)
// - if key is 0 the subject is returned unchanged, key 1 and 2 are the two single-iteration traversals
item listTraverse(item subject, item key) {
	if (key++) {
		int i,j;
		for (i=1; i<=key>>1; i<<=1)
			subject = space[j=subject+(subject<<1)+(key&i?1:0)]?space[j]:(space[j]=listInsert());
		}
	return subject;
	}

// Get the value (payload key) of the subject Item
item listGetValue(item subject) {
	return space[subject+(subject<<1)+2];
	}

// Set the payload key of the subject Item to the passed value
item listSetValue(item subject, item value) {
	return space[subject+(subject<<1)+2] = value;
	}


// Print listSpace statistics
// - currently just counts how many nodes have payloads and displays content
void listStats() {
	int i,j,p=0;
	printf("\nlistStatistics:\n");
	for (i=0; i<MAXITEMS; i++) if (listGetValue(i)) p++;
	printf("\t%d of %d items in use:\n",p,MAXITEMS);
	//for (i=0; i<MAXITEMS; i++) if (j=listGetValue(i)) printf("    %d = %d\n",i,j);
	printf("\n\n");
	}


// ----------------------------------------------------------------------------------------- //
// Trie
// - not really part of listSpace, but needed by env's with no hash-tables
// - uses ascii traversal by reserving first list items
// - trie sets/gets list items using ascii-traversal

item trieGetValue(unsigned char *key) {
	item subject = nodeTRIE;
	while(*key) subject = listTraverse(subject,*key++);
	return listGetValue(subject);
	}

item trieSetValue(unsigned char *key, item value) {
	item subject = nodeTRIE;
	while(*key) subject = listTraverse(subject,*key++);
	return listSetValue(subject,value);
	}