static int Add(Bst *t, int ParentNode, BOOL IsLeft, const void *Data) { static const Bst_NodeHead NewHead = {-1, -1, -1}; int32_t NewElement = GetUnusedNode(t); if( NewElement >= 0 ) { Bst_NodeHead *NewZone = Array_GetBySubscript(t -> Nodes, NewElement); memcpy(NewZone, &NewHead, sizeof(Bst_NodeHead)); if( ParentNode >= 0 ) { Bst_NodeHead *Parent = Array_GetBySubscript(t -> Nodes, ParentNode); NewZone -> Parent = ParentNode; if( IsLeft == TRUE ) { Parent -> Left = NewElement; } else { Parent -> Right = NewElement; } } else { NewZone -> Parent = -1; t -> Root = NewElement; } memcpy(NewZone + 1, Data, t -> Nodes -> DataLength - sizeof(Bst_NodeHead)); return 0; } else { return -1; } }
static int CacheHT_CreateNewNode(CacheHT *h, uint32_t ChunkSize, Cht_Node **Out, void *Boundary) { int NewNode_i; Cht_Node *NewNode; Array *NodeChunk = &(h -> NodeChunk); NewNode_i = Array_PushBack(NodeChunk, NULL, Boundary); if( NewNode_i < 0 ) { return -1; } NewNode = (Cht_Node *)Array_GetBySubscript(NodeChunk, NewNode_i); NewNode -> Next = -1; NewNode -> Length = ChunkSize; if( Out != NULL ) { *Out = NewNode; } return NewNode_i; }
int CacheHT_InsertToSlot(CacheHT *h, const char *Key, int Node_index, Cht_Node *Node, int *HashValue ) { int Slot_i; Cht_Slot *Slot; if( h == NULL || Key == NULL || Node_index < 0 || Node == NULL ) return -1; if( HashValue != NULL ) { Slot_i = (*HashValue) % (h -> Slots.Allocated); } else { Slot_i = ELFHash(Key, 0) % (h -> Slots.Allocated); } Node -> Slot = Slot_i; Slot = (Cht_Slot *)Array_GetBySubscript(&(h -> Slots), Slot_i); if( Slot == NULL ) return -2; Node -> Next = Slot -> Next; Slot -> Next = Node_index; return 0; }
int Bst_Add(Bst *t, const void *Data) { if( t -> Root == -1 ) { return Add(t, -1, FALSE, Data); } else { int32_t CurrentNode = t -> Root; Bst_NodeHead *Current; while( TRUE ) { Current = Array_GetBySubscript(t -> Nodes, CurrentNode); if( (t -> Compare)(Data, ((char *)Current) + sizeof(Bst_NodeHead)) <= 0 ) { if( Current -> Left == -1 ) { return Add(t, CurrentNode, TRUE, Data); } else { CurrentNode = Current -> Left; } } else { if( Current -> Right == -1 ) { return Add(t, CurrentNode, FALSE, Data); } else { CurrentNode = Current -> Right; } } } } }
const void *Bst_Search(Bst *t, const void *Data, const void *Start) { int32_t CurrentNode; const Bst_NodeHead *Current; int CompareResult; if( Start == NULL ) { CurrentNode = t -> Root; } else { const Bst_NodeHead *Next = (const Bst_NodeHead *)((char *)Start) - sizeof(Bst_NodeHead); CurrentNode = Next -> Left; } while( CurrentNode >= 0 ) { Current = Array_GetBySubscript(t -> Nodes, CurrentNode); CompareResult = (t -> Compare)(Data, ((char *)Current) + sizeof(Bst_NodeHead)); if( CompareResult < 0 ) { CurrentNode = Current -> Left; } else if( CompareResult > 0 ) { CurrentNode = Current -> Right; } else { return ((char *)Current) + sizeof(Bst_NodeHead); } } return NULL; }
Cht_Node *CacheHT_Get(CacheHT *h, const char *Key, Cht_Node *Start, int *HashValue) { Cht_Node *Node; if( h == NULL || Key == NULL) return NULL; if( Start == NULL ) { int Slot_i; Cht_Slot *Slot; if( HashValue != NULL ) { Slot_i = (*HashValue) % (h -> Slots.Allocated); } else { Slot_i = ELFHash(Key, 0) % (h -> Slots.Allocated); } Slot = (Cht_Slot *)Array_GetBySubscript(&(h -> Slots), Slot_i); Node = (Cht_Node *)Array_GetBySubscript(&(h -> NodeChunk), Slot -> Next); if( Node == NULL ) return NULL; return Node; } else { Node = (Cht_Node *)Array_GetBySubscript(&(h -> NodeChunk), Start -> Next); if( Node == NULL ) return NULL; return Node; } }
static int32_t GetUnusedNode(Bst *t) { if( t -> FreeList > 0 ) { int32_t ReturnValue = t -> FreeList; const Bst_NodeHead *NextNode; NextNode = Array_GetBySubscript(t -> Nodes, t -> FreeList); t -> FreeList = NextNode -> Right; return ReturnValue; } else { return Array_PushBack(t -> Nodes, NULL, NULL); } }
static void ThereIsAnEnd(CacheHT *h, int Slot_i, Cht_Slot *Slot) { int i = Slot -> Next; Cht_Node *Node; while( i >= 0 ) { Node = Array_GetBySubscript(&(h -> NodeChunk), i); if( Node -> Slot != Slot_i ) { printf("--------------------ERROR\n"); } i = Node -> Next; } }
int32_t CacheHT_FindUnusedNode(CacheHT *h, uint32_t ChunkSize, Cht_Node **Out, void *Boundary, BOOL *NewCreated ) { int32_t Subscript = h -> FreeList; Cht_Node *FirstNode = NULL; Cht_Node *SecondNode = NULL; Array *NodeChunk = &(h -> NodeChunk); while ( Subscript >= 0 ) { FirstNode = SecondNode; SecondNode = (Cht_Node *)Array_GetBySubscript(NodeChunk, Subscript); if( SecondNode -> Length == ChunkSize ) { if( FirstNode == NULL ) { h -> FreeList = SecondNode -> Next; } else { FirstNode -> Next = SecondNode -> Next; } SecondNode -> Next = -1; if( Out != NULL ) { *Out = SecondNode; } *NewCreated = FALSE; return Subscript; } Subscript = SecondNode -> Next; } *NewCreated = TRUE; return CacheHT_CreateNewNode(h, ChunkSize, Out, Boundary); }
int CacheHT_RemoveFromSlot(CacheHT *h, int32_t SubScriptOfNode, Cht_Node *Node) { Array *NodeChunk = &(h -> NodeChunk); Cht_Slot *Slot; Cht_Node *Predecesor; if( Node -> Slot < 0 ) { return 0; } Slot = (Cht_Slot *)Array_GetBySubscript(&(h -> Slots), Node -> Slot); if( Slot == NULL ) { return -1; } Predecesor = CacheHT_FindPredecesor(h, Slot, SubScriptOfNode); if( Predecesor == NULL ) { Slot -> Next = Node -> Next; } else { Predecesor -> Next = Node -> Next; } /* If this node is not the last one of NodeChunk, add it into free list, * or simply delete it from NodeChunk */ if( SubScriptOfNode != NodeChunk -> Used - 1 ) { Node -> Next = h -> FreeList; h -> FreeList = SubScriptOfNode; Node -> Slot = -1; } else { --(NodeChunk -> Used); } return 0; }
struct sockaddr *AddressList_GetOne(AddressList *a, sa_family_t *family) { struct _Address *Result; if( a == NULL ) { return 0; } Result = (struct _Address *)Array_GetBySubscript(&(a -> AddressList), a -> Counter % Array_GetUsed(&(a -> AddressList))); if( Result == NULL ) { return NULL; } else { if( family != NULL ) { *family = Result -> family; } return (struct sockaddr *)&(Result -> Addr); } }
int CacheHT_Init(CacheHT *h, char *BaseAddr, int CacheSize) { int loop; h -> Slots.Used = CacheHT_CalculateSlotCount(CacheSize); h -> Slots.DataLength = sizeof(Cht_Slot); h -> Slots.Data = BaseAddr + CacheSize - (h -> Slots.DataLength) * (h -> Slots.Used); h -> Slots.Allocated = h -> Slots.Used; for(loop = 0; loop != h -> Slots.Allocated; ++loop) { ((Cht_Slot *)Array_GetBySubscript(&(h -> Slots), loop)) -> Next = -1; } h -> NodeChunk.DataLength = sizeof(Cht_Node); h -> NodeChunk.Data = h -> Slots.Data - h -> NodeChunk.DataLength; h -> NodeChunk.Used = 0; h -> NodeChunk.Allocated = -1; h -> FreeList = -1; return 0; }
static Cht_Node *CacheHT_FindPredecesor(CacheHT *h, Cht_Slot *Slot, int32_t SubScriptOfNode) { int Next = Slot -> Next; Cht_Node *Node; if( Next == SubScriptOfNode ) { return NULL; } while( Next >= 0 ) { Node = Array_GetBySubscript(&(h -> NodeChunk), Next); Next = Node -> Next; if( Next == SubScriptOfNode ) { return Node; } } return NULL; }
BOOL StringChunk_Match_OnlyWildCard(StringChunk *dl, const char *Str, char **Data ) { EntryForString *FoundEntry; const char *FoundString; int loop; for( loop = 0; loop != Array_GetUsed(&(dl -> List_W_Pos)); ++loop ) { FoundEntry = (EntryForString *)Array_GetBySubscript(&(dl -> List_W_Pos), loop); if( FoundEntry != NULL ) { FoundString = StringList_GetByOffset(&(dl -> List_W), FoundEntry -> OffsetOfString); if( WILDCARD_MATCH(FoundString, Str) == WILDCARD_MATCHED ) { if( FoundEntry -> OffsetOfData >=0 && Data != NULL ) { *Data = ExtendableBuffer_GetPositionByOffset( &(dl -> AdditionalDataChunk), FoundEntry -> OffsetOfData ); } return TRUE; } } else { return FALSE; } } return FALSE; }