Difference between revisions of "ListSpace.c"

From Organic Design wiki
(Add hash-table functions)
m (Nad moved page ListSpace.h to ListSpace.c over redirect)
 
(120 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;
  
// Create a new listItem in the space and return its index
+
// Prototypes
item listInsert() {
+
int listInit();
//printf("listInsert(): new item %d\n", items);
+
int listExit();
return items++;
+
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);
  
// Start at subject listItem and traverse the object as an association to a new listItem
 
// - object is also a listItem reference and its binary address is used as the traversal path
 
// - subject and object (all list-item references are ints starting at item 0)
 
item listTraverse(item subject, item object) {
 
object += 2; // tmp: can't traverse items 0 or 1
 
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
+
// ----------------------------------------------------------------------------------------- //
item listGetValue(item subject) {
+
// listSpace.c
return space[subject*3+2];
 
}
 
  
// Set the payload key of the subject Item to the passed value
+
int listInit() {
void listSetValue(item subject, item value) {
+
// all these are tmp and should be handled with new pointer-list
space[subject*3+2] = value;
+
space = calloc(MAXITEMS,3*sizeof(item));
 +
nssBuf = malloc(30);
 +
return EXIT_SUCCESS;
 
}
 
}
  
// The following four functions are used internally by hashSet/Get
+
int listExit() {
// - Treat each character in text-keys as a list-item-index to traverse from root
+
free(space);
// - 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 hashTraverse(char *text) {
 
item subject = ROOT;
 
int i;
 
for (i=0; i<strlen(text); i++)
 
subject = listTraverse(subject, (item)text[i]);
 
return subject;
 
 
}
 
}
  
void *hashReturnPointer(int index) {
+
// Create a new listItem in the space and return its index
void *ptr;
+
item listInsert() {
return ptr;
+
// 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;
 
}
 
}
  
int hashInsertPointer(void *ptr) {
+
// Move the subject onto the free-list
int index;
+
item listRemove(item subject) {
return index;
+
return subject;
 
}
 
}
  
void hashRemovePointer(int index) {
+
// 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 pointer to the data associated with the passed text-key
+
// Get the value (payload key) of the subject Item
void *hashGetValue(char* key) {
+
item listGetValue(item subject) {
return hashReturnPointer((int)listGetValue(hashTraverse(key)));
+
return space[subject+(subject<<1)+2];
 
}
 
}
  
// Set the data-pointer associated with the passed text-key
+
// Set the payload key of the subject Item to the passed value
void hashSetValue(char* key, void *value) {
+
item listSetValue(item subject, item value) {
*hashReturnPointer((int)listGetValue(hashTraverse(key))) = value;
+
return space[subject+(subject<<1)+2] = value;
 
}
 
}
 
// 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);
	}