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;
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
Type | Class | Notes | |
---|---|---|---|
HTT_INVALID | None | Cannot be selected | |
HTT_GLBL_VAR | CHashGlblVar* | ->data_addr points to data | |
HTT_CLASS | CHashClass* | Can be used for metadata | |
HTT_FRAME_PTR | CHashGeneric* | This can be set with | FramePtrAdd (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.
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;
}
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