DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦c18aa1ba3⟧ Ada Source

    Length: 23552 (0x5c00)
    Types: Ada Source
    Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Sorted_List_Generic, seg_0046ad

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦5a81ac88f⟧ »Space Info Vol 1« 
        └─⟦this⟧ 

E3 Source Code



package body Sorted_List_Generic is

    First_Position : constant Natural := Natural (Positions'First);
    Done_Position  : constant Natural := Natural'Pred (First_Position);

    --| @SUMMARY Task that manages the internal free-list.
    --| @SPECIAL_NOTES Use of a task ensures concurrency safety.
    --|
    task Free_List_Manager is

        entry Get_Node (The_Node : out Pointer; Contents : in Element);

        entry Free_Node (This_Node : in out Pointer);

    end Free_List_Manager;

    task body Free_List_Manager is

        --| @SPECIAL_NOTES Package/task state: the internal free list.
        --|
        Free_List : Pointer := null;

    begin
        loop
            select
                accept Get_Node (The_Node : out Pointer;
                                 Contents : in  Element) do
                    declare
                        New_Node : Pointer := null;
                    begin
                        if Free_Lis = null then
                            New_Node := new Node'(Contents => Contents,  
                                                  Next     => null,
                                                  Previous => null);
                        else
                            New_Node          := Free_List;
                            Free_List         := Free_List.Next;
                            New_Node.Next     := null;
                            New_Node.Previous := null;  
                            New_Node.Contents := Contents;
                        end if;  
                        The_Node := New_Node;
                    end;
                end Get_Node;
            or
                accept Free_Node (This_Node : in out Pointer) do
                    This_Node.Previous := null;
                    This_Node.Next     := Free_List;
                    Free_List          := This_Node;
                end Free_Node;
            or
                terminate;
            end select;
        end loop;
    end Free_List_Manager;

    --| @DESCRIPTION Walks a pointer to an arbitrary position in the
    --| list.
    --|
    --| @SPECIAL_NOTES Blows up if position is out of range. Unsafe
    --| for export.
    --|
    procedure Set (This_Pointer     : in out Pointer;
                   To_This_Position : in     Positions;
                   In_This_List     : in out List;
                   Permanently      :        Boolean := False) is
    begin
        This_Pointer := In_This_List.First;
        for Counter in First_Position .. Natural (To_This_Position) - 1 loop
            This_Pointer := This_Pointer.Next;
        end loop;
        if Permanently then
            In_This_List.Current  := This_Pointer;
            In_This_List.Position := Natural (To_This_Position);
        end if;
    end Set;

    function Create return List is

        The_List : List;

    begin  
        return The_List;  
    end Create;

    function Is_Empty (This_List : in List) return Boolean is  
    begin  
        return Elements_In (This_List) = 0;  
    end Is_Empty;

    function Elements_In (This_List : in List) return Natural is  
    begin  
        return This_List.Count;  
    end Elements_In;

    function Copy (Of_List : in List) return List is

        Current : Pointer := Of_List.First;

        New_List : List := Create;

    begin
        while Current /= null loop
            Add (New_List, Copy (Current.Contents), Insert);
            Current := Current.Next;
        end loop;  
        if not Done (Of_List) then
            Set (New_List, Position (Of_List));
        end if;
        return New_List;
    end Copy;

    procedure Reset_To_First (This_List : in out List) is  
    begin  
        This_List.Current := This_List.First;
        if This_List.First = null then
            This_List.Position := Done_Position;
        else
            This_List.Position := First_Position;
        end if;
    end Reset_To_First;

    procedure Reset_To_Last (This_List : in out List) is
    begin
        This_List.Current := This_List.Last;
        if This_List.Last = null then
            This_List.Position := Done_Position;
        else
            This_List.Position := This_List.Count;
        end if;
    end Reset_To_Last;

    function Done (This_List : in List) return Boolean is
    begin
        return This_List.Current = null;
    end Done;

    function At_First (This_List : in List) return Boolean is
    begin
        return not Done (This_List) and then
                  This_List.Current = This_List.First;
    end At_First;

    function At_Last (This_List : in List) return Boolean is
    begin
        return not Done (This_List) and then This_List.Current = This_List.Last;
    end At_Last;

    procedure Previous (This_List : in out List) is
    begin
        This_List.Current  : This_List.Current.Previous;
        This_List.Position := This_List.Position - 1;

    exception
        when Constraint_Error =>
            raise No_Previous_Element;

    end Previous;

    procedure Next (This_List : in out List) is  
    begin
        This_List.Current  := This_List.Current.Next;
        This_List.Position := This_List.Position + 1;

    exception
        when Constraint_Error =>
            raise No_Next_Element;

    end Next;

    function Current (This_List : in List) return Element is  
    begin  
        return This_List.Current.Contents;

    exception
        when Constraint_Error =>
            raise No_Current_Element;

    end Current;

    function Position (In_List : in List) return Positions is
    begin
        return Positions (In_List.Position);

    exception
        when Constraint_Error =>
            raise No_Current_Element;

    end Position;

    procedure Set (This_List : in ut List; To_Position : in Positions) is
    begin  
        Set (This_List.Current, To_Position, This_List, Permanently => True);

    exception
        when Constraint_Error =>
            raise Out_Of_Range;

    end Set;

    --| @ALGORITHM Walks a "probe" pointer along list, leaving internal
    --| list pointers undisturbed.
    --|
    function Element_At (This_Position : in Positions; In_List : in List)
                        return Element is

        The_List : List := In_List;

        Probe : Pointer := null;

    begin
        Set (Probe, This_Position, The_List);
        return Probe.Contents;

    exception
        when Constraint_Error =>
            raise Out_Of_Range;

    end Element_At;

    procedure Add (To_List            : in out List;  
                   This_Element       : in     Element;
                   Duplicate_Reaction : in     Duplicate_Reactions) is

        procedure Add_Initial_Element is

            New_Node : Pointer := null;

        begin
            Free_List_Manager.Get_Node (New_Node, Contents => This_Element);
            To_List.Position := First_Position;
            To_List.Current  := New_Node;
            To_List.First    := New_Node;  
            To_List.Last     := New_Node;
            To_List.Count    := 1;
        end Add_Initial_Element;

        procedure Add_Subsequent_Element is

            Add_Point : Pointer := To_List.First;

            Add_Position : Positions := Positions (First_Position);

            procedure Add_Before is

                New_Node : Pointer := null;

            begin
                Free_List_Manager.Get_Node (New_Node, Contents => This_Element);
                New_Node.Previous  := Add_Point.Previous;
                Add_Point.Previous := New_Node;
                New_Node.Next      := Add_Point;
                if New_Node.Previous /= null then
                    New_Node.Previous.Next := New_Node;
                end if;
                if To_List.First = Add_Point then
                    To_List.First := New_Node;
                end if;
                To_List.Count := To_List.Count + 1;
                if Position (To_List) >= Add_Position then
                    --
                    -- Insertion was before the original position, so the
                    -- position needs to be shifted over by one.
                    --
                    To_List.Position := To_List.Position + 1;
                end if;
            end Add_Before;

            procedure Add_After is

                New_Node : Pointer := null;

            begin
                Free_List_Manager.Get_Node (New_Node, Contents => This_Element);
                New_Node.Next     := Add_Point.Next;
                Add_Point.Next    := New_Node;
                New_Node.Previous := Add_Point;
                if New_Node.Next /= null then
                    New_Node.Next.Previous := New_Node;
                end if;
                if To_List.Last = Add_Point then
                    To_List.Last := New_Node;
                end if;
                To_List.Count := To_List.Count + 1;
                if Position (To_List) > Add_Position then
                    --
                    -- Insertion was before the original position, so the
                    -- position needs to be shifted over by one.
                    --
                    To_List.Position := To_List.Position + 1;
                end if;
            end Add_After;

        begin
            loop
                if Add_Point = null then
                    --
                    -- Element is greater than all others in list, so append to
                    -- end of list.
                    --
                    Add_Position := Add_Position - 1;
                    Add_Point    := To_List.Last;
                    Add_After;
                    exit;
                elsif This_Element < Add_Point.Contents then
                    --
                    -- Element is less than current element in list, so add
                    -- before current element.
                    --
                    Add_Before;
                    exit;
                elsif not (Add_Point.Contents < This_Element) then
                    --
                    -- Element is not < and not >, so must be equal
                    -- to current element in list.
                    --
                    case Duplicate_Reaction is
                        when Disallow =>
                            raise Duplicate_Element;
                        when Overwrite =>
                            Add_Point.Contents := This_Element;
                            exit;
                        when Insert =>
                            --
                            -- Keep walking down list until pass all duplicates
                            -- of current element. Will either encounter an
                            -- element larger than the element being added, or
                            -- will encounter end of list. Both cases are
                            -- already covered.
                            --
                            null;
                    end case;
                end if;
                Add_Point    := Add_Point.Next;
                Add_Position := Add_Position + 1;
            end loop;  
        end Add_Subsequent_Element;

    begin
        if Is_Empty (To_List) then
            Add_Initial_Element;
        else
            Add_Subsequent_Element;
        end if;  
    end Add;

    procedure Delete (From_List : in out List) is
    begin
        Delete (From_List, Position (From_List));

    exception
        when others =>
            raise No_Current_Element;

    end Delete;

    procedure Delete (From_List : in out List; At_Position : in Positions) is

        Delete_Point : Pointer := null;

    begin  
        Set (Delete_Point, At_Position, From_List);
        if From_List.Current = Delete_Point then
            From_List.Current := Delete_Point.Next;
        end if;
        if From_List.First = Delete_Point then
            From_List.First := Delete_Point.Next;
        end if;
        if From_List.Last = Delete_Point then
            From_List.Last := Delete_Point.Previous;
        end if;  
        if Delete_Point.Previous /= null then
            Delete_Point.Previous.Next := Delete_Point.Next;
        end if;
        if Delete_Point.Next /= null then
            Delete_Point.Next.Previous := Delete_Point.Previous;
        end if;  
        Free_List_Manager.Free_Node (Delete_Point);  
        From_List.Count := From_List.Count - 1;
        if Position (From_List) > At_Position then
            --
            -- Deletion was before the original position, so the
            -- position needs to be shifted over by one.
            --
            From_List.Position := From_List.Position - 1;
        end if;

    exception
        when others =>
            raise Out_Of_Range;

    end Delete;

    procedure Dispose (Of_This_List : in out List) is
    begin
        Reset_To_First (Of_This_List);
        while not Done (Of_This_List) loop
            Delete (Of_This_List);
        end loop;
    end Dispose;

end Sorted_List_Generic;

E3 Meta Data

    nblk1=16
    nid=0
    hdr6=2c
        [0x00] rec0=20 rec1=00 rec2=01 rec3=046
        [0x01] rec0=00 rec1=00 rec2=16 rec3=002
        [0x02] rec0=15 rec1=00 rec2=02 rec3=016
        [0x03] rec0=01 rec1=00 rec2=15 rec3=020
        [0x04] rec0=1f rec1=00 rec2=03 rec3=01e
        [0x05] rec0=23 rec1=00 rec2=04 rec3=020
        [0x06] rec0=20 rec1=00 rec2=05 rec3=038
        [0x07] rec0=00 rec1=00 rec2=14 rec3=002
        [0x08] rec0=28 rec1=00 rec2=06 rec3=044
        [0x09] rec0=00 rec1=00 rec2=13 rec3=002
        [0x0a] rec0=24 rec1=00 rec2=07 rec3=006
        [0x0b] rec0=1b rec1=00 rec2=08 rec3=04c
        [0x0c] rec0=00 rec1=00 rec2=12 rec3=022
        [0x0d] rec0=19 rec1=00 rec2=09 rec3=04e
        [0x0e] rec0=00 rec1=00 rec2=11 rec3=00e
        [0x0f] rec0=1a rec1=00 rec2=0a rec3=010
        [0x10] rec0=00 rec1=00 rec2=10 rec3=006
        [0x11] rec0=15 rec1=00 rec2=0b rec3=046
        [0x12] rec0=1f rec1=00 rec2=0c rec3=090
        [0x13] rec0=00 rec1=00 rec2=0f rec3=006
        [0x14] rec0=1a rec1=00 rec2=0d rec3=038
        [0x15] rec0=14 rec1=00 rec2=0e rec3=001
    tail 0x215004906815c66d0f474 0x42a00088462061e03