with Ada.Unchecked_Deallocation; with Interfaces; use Interfaces; package body Sax.HTable is procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Element, Element_Ptr); procedure Unchecked_Free is new Ada.Unchecked_Deallocation (Htable_Item, Item_Ptr); ----------- -- Reset -- ----------- procedure Reset (Hash_Table : in out HTable) is Item, Tmp : Item_Ptr; begin for Index in Hash_Table.Table'Range loop Item := Hash_Table.Table (Index); while Item /= null loop Free (Item.Elem.all); Unchecked_Free (Item.Elem); Tmp := Item; Item := Item.Next; Unchecked_Free (Tmp); end loop; Hash_Table.Table (Index) := null; end loop; end Reset; --------- -- Set -- --------- procedure Set (Hash_Table : in out HTable; E : Element) is Index : constant Unsigned_32 := Hash (Get_Key (E)) mod Hash_Table.Size + 1; begin Hash_Table.Table (Index) := new Htable_Item' (Elem => new Element'(E), Next => Hash_Table.Table (Index)); end Set; --------- -- Get -- --------- function Get (Hash_Table : HTable; K : Key) return Element is Elmt : Item_Ptr := Hash_Table.Table (Hash (K) mod Hash_Table.Size + 1); begin while Elmt /= null loop if Equal (Get_Key (Elmt.Elem.all), K) then return Elmt.Elem.all; end if; Elmt := Elmt.Next; end loop; return Empty_Element; end Get; ------------ -- Remove -- ------------ procedure Remove (Hash_Table : in out HTable; K : Key) is Index : constant Unsigned_32 := Hash (K) mod Hash_Table.Size + 1; Elmt : Item_Ptr := Hash_Table.Table (Index); Next_Elmt : Item_Ptr; begin if Elmt = null then return; elsif Equal (Get_Key (Elmt.Elem.all), K) then Hash_Table.Table (Index) := Elmt.Next; else loop Next_Elmt := Elmt.Next; if Next_Elmt = null then return; elsif Equal (Get_Key (Next_Elmt.Elem.all), K) then Elmt.Next := Next_Elmt.Next; Free (Next_Elmt.Elem.all); Unchecked_Free (Next_Elmt.Elem); Unchecked_Free (Next_Elmt); return; end if; Elmt := Next_Elmt; end loop; end if; end Remove; ----------- -- First -- ----------- function First (Hash_Table : HTable) return Iterator is begin for Index in Hash_Table.Table'Range loop if Hash_Table.Table (Index) /= null then return (Index => Index, Item => Hash_Table.Table (Index)); end if; end loop; return No_Iterator; end First; ---------- -- Next -- ---------- procedure Next (Hash_Table : in out HTable; Iter : in out Iterator) is begin pragma Assert (Iter /= No_Iterator); Iter.Item := Iter.Item.Next; if Iter.Item /= null then return; end if; loop Iter.Index := Unsigned_32'Succ (Iter.Index); exit when Iter.Index > Hash_Table.Table'Last or else Hash_Table.Table (Iter.Index) /= null; end loop; if Iter.Index > Hash_Table.Table'Last then Iter := No_Iterator; else Iter.Item := Hash_Table.Table (Iter.Index); end if; end Next; function Current (Iter : Iterator) return Element is begin return Iter.Item.Elem.all; end Current; end Sax.HTable;