Skip to main content

Data structures

Data structures are cool structures that store data.

HashTable

Hash tables are like dictionaries you can add stuff to on the fly,each CTask has a hash table which you can get via Fs . Each item in the hash table has a type and str,to look for a define do this

#define ONION 10
CHashDefineStr *d=HashFind("ONION",Fs->hash_table,HTT_DEFINE_STR);
"%s\n",d->data;

Hash table

In TempleOS,you can add items to the table,we first need to MAlloc an item first, then fill in the table

CHashDefineStr *d=CAlloc(sizeof(CHashDefineStr));
d->str=StrNew("Hello"); //Must allocate string on heap
d->type=HTT_DEFINE_STR;
d->data=StrNew("10");
HashAdd(d,Fs->hash_table);
//We added the macro Hello into the hash table
"%d\n",Hello;

You can make your own hash-tables viaHashTableNew. The size must be a power of 2. You can free it with HashTableDel.

CHashTable *ht=HashTableNew(0x100);
CHashGeneric *ent=CAlloc(sizeof CHashGeneric);
ent->user_data0=1;
ent->user_data1=2;
ent->user_data2=3;
ent->type=HTT_FRAME_PTR;
ent->str=StrNew("look");
HashAdd(ent,ht);
CHashGeneric *g=HashFind("look",ht,HTT_FRAME_PTR);
"%d,%d,%d\n",g->user_data0,g->user_data1,g->user_data2;
HashTableDel(ht);

As you may have seen,each CHash item has a type. Here is a list of he some of the HTT types and what class they use

TypeClassNotes
HTT_INVALIDNoneCannot be selected
HTT_GLBL_VARCHashGlblVar*->data_addr points to data
HTT_CLASSCHashClass*Can be used for metadata
HTT_FRAME_PTRCHashGeneric*This can be set withFramePtrAdd(use FramePtr to get)

Fifo

Fifo means "First In First Out". It is like a stack of papers,the first paper you put in is the first one you get out,In TempleOS,CFifo's must be aligned to a power of 2.

FIFO

CFifoI64 *fifo=FifoI64New(0x100);

We can insert items via FifoI64Ins.

I64 bottom;
FifoI64Ins(fifo,1);
FifoI64Ins(fifo,2);
FifoI64Ins(fifo,3); //1 is on bottom

Use FifoI64Rem to remove an item.

FifoI64Rem(fifo,&bottom);
"%d\n",bottom;
FifoI64Rem(fifo,&bottom);
"%d\n",bottom;
FifoI64Rem(fifo,&bottom);
"%d\n",bottom;
FifoI64Del(fifo);

There are 2 variants of Fifo's in TempleOS,the CFifoI64,CFifoU8. One hold's I64's and the other holds U8's.

Once a Fifo gets full,the oldest item will be removed for you(It's initial size it created with FifoI64New/FifoU8New). You can get the current size via FifoI64Cnt. You can empty all items in the fifo with FifoI64Flush,or you can peak at the bottom by doing this

I64 bottom;
FifoI64Peek(fifo,&bottom);

Circular Queue

These are useful as(unlike an array) you do not need to resize an array to add more items,and removing items is very easy. A Circular Queue is bodacious as it a chain of items,and inserting/removing items only requires editing one chain link(and not the whole chain). So what does it look like in action.

You will need to have your class have he base class of CQue . You can do it like this:

class CQInt:CQue { //CQue is the baseclass
I64 value;
};

Each node has a last and next member,which point to the previous and next item in the chain. Each chain item has a head element,and because the chains are circular,the chain starts and ends at head. So when we loop,we check for the head element,here is part of an example:

"I have %d elements.\n",QueCnt(head); //ONLY call on head
//The queue is circular. It starts AND ENDS at head
CQInt *cur=head->next; //Goto element after head
while(cur!=head) { //Ends at head
"I found a %d\n",cur->value;
cur=cur->next;
}

Wrap around

When we create a chain link,we CAlloc it to allocation some memory for it. UseQueInit to initialize the node .We use QueIns(new,head->last); to add it. With that being said,let's see the full example.

class CQInt:CQue {
I64 value;
};
CQue *head=CAlloc(sizeof CQue);
CQInt *one=CAlloc(sizeof CQInt);
CQInt *two=CAlloc(sizeof CQInt);
CQInt *three=CAlloc(sizeof CQInt);
QueInit(head);
QueInit(one);
QueInit(two);
QueInit(three);
//
one->value=1;
two->value=2;
three->value=3;

//inserted element goes on the left.
QueIns(one,head->last); //last now points to one
QueIns(two,head->last); //last now points to two
QueIns(three,head->last); //last now points to three

"I have %d elements.\n",QueCnt(head); //ONLY call on head
//The queue is circular. It starts AND ENDS at head
CQInt *cur=head->next; //Goto element after head
while(cur!=head) { //Ends at head
"I found a %d\n",cur->value;
cur=cur->next;
}
QueDel(head); //Bye bye