?? TITLE := 'NOS/VE Set Management : Read AST' ??
MODULE stm$read_ast_r1;
?? RIGHT := 110 ??

{ PURPOSE:
{   This module includes all those procedures that will read the active set
{   table, but will not modify it.  These procedures will all run at ring 1.

?? NEWTITLE := '  Global Declarations Referenced by this module' ??
?? PUSH (LISTEXT := ON) ??
*copyc stc$max_num_members_on_set
*copyc ste$error_condition_codes
*copyc stt$number_of_members
*copyc stt$number_of_sets
*copyc stt$set_list
*copyc stt$volume_list
?? POP ??
*copyc osp$set_status_abnormal
*copyc stp$search_mel_for_vol
*copyc stv$p_ast
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$get_active_set_list', EJECT ??
*copy sth$get_active_set_list

  PROCEDURE [XDCL, #GATE] stp$get_active_set_list
    (VAR set_list: stt$set_list;
     VAR actual_number_of_sets: stt$number_of_sets);

    VAR
      i: stt$ast_index,
      entry_p: ^stt$active_set_entry,
      size_of_input_set_list: integer;

    size_of_input_set_list := UPPERBOUND (set_list);
    actual_number_of_sets := 0;

    IF stv$p_ast <> NIL THEN
      FOR i := 1 TO UPPERBOUND (stv$p_ast^) DO
        entry_p := ^stv$p_ast^ [i];
        IF entry_p^.entry_type = stc$valid THEN
          actual_number_of_sets := actual_number_of_sets + 1;
          IF actual_number_of_sets <= size_of_input_set_list THEN
            set_list [actual_number_of_sets] := entry_p^.set_name;
          IFEND;
        IFEND;
      FOREND;
    IFEND;

  PROCEND stp$get_active_set_list;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$get_volumes_by_ast_index', EJECT ??
*copy sth$get_volumes_by_ast_index

  PROCEDURE [XDCL, #GATE] stp$get_volumes_by_ast_index
    (    set_index: stt$ast_index;
         starting_member_index: stt$number_of_members;
     VAR master_vol: stt$volume_info;
     VAR member_vsn_list: stt$volume_list;
     VAR number_of_members: stt$number_of_members);

    VAR
      ast_entry_p: ^stt$active_set_entry,
      entry_p: ^stt$member_entry,
      external_set_name: stt$set_name,
      info_p: ^stt$volume_info,
      mel_index: stt$mel_index,
      member_list_index: stt$number_of_members,
      member_entry_list_p: ^stt$member_entry_list;

    ast_entry_p := ^stv$p_ast^ [set_index];
    number_of_members := 0;
    member_list_index := starting_member_index;
    external_set_name := ast_entry_p^.set_name;
    master_vol.recorded_vsn := ast_entry_p^.master_vsn;
    master_vol.internal_vsn := ast_entry_p^.master_internal_vsn;
    IF ast_entry_p^.master_ever_up THEN
      master_vol.volume_activity := ast_entry_p^.master_volume_activity;
      master_vol.dm_packet_storage := ast_entry_p^.master_dm_packet_storage;
    ELSE
      master_vol.volume_activity.volume_activity_status := stc$inactive;
      master_vol.dm_packet_storage.dm_packet_ever_stored := FALSE;
    IFEND;
    master_vol.set_name := external_set_name;
    member_entry_list_p := ast_entry_p^.p_member_entry_list;

    IF member_entry_list_p <> NIL THEN
      FOR mel_index := LOWERBOUND (member_entry_list_p^) TO UPPERBOUND (member_entry_list_p^) DO
        entry_p := ^member_entry_list_p^ [mel_index];
        IF entry_p^.entry_type = stc$valid THEN
          number_of_members := number_of_members + 1;
          IF member_list_index <= UPPERBOUND (member_vsn_list) THEN
            info_p := ^member_vsn_list [member_list_index];
            info_p^.recorded_vsn := entry_p^.member_vsn;
            info_p^.internal_vsn := entry_p^.member_internal_vsn;
            info_p^.set_name := external_set_name;
            info_p^.volume_activity := entry_p^.member_volume_activity;
            info_p^.dm_packet_storage := entry_p^.member_dm_packet_storage;
            member_list_index := member_list_index + 1;
          IFEND;
        IFEND;
      FOREND;
    IFEND;

  PROCEND stp$get_volumes_by_ast_index;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$members_active_on_set', EJECT ??
*copy sth$members_active_on_set

  PROCEDURE [XDCL] stp$members_active_on_set
    (    ast_index: stt$ast_index;
     VAR members_active_on_set: boolean);

    VAR
      mel_index: stt$mel_index,
      p_member_entry_list: ^stt$member_entry_list;

    p_member_entry_list := stv$p_ast^ [ast_index].p_member_entry_list;
    members_active_on_set := FALSE;
    IF p_member_entry_list <> NIL THEN
      FOR mel_index := LOWERBOUND (p_member_entry_list^) TO UPPERBOUND (p_member_entry_list^) DO
        IF p_member_entry_list^ [mel_index].entry_type = stc$valid THEN
          IF p_member_entry_list^ [mel_index].member_volume_activity.volume_activity_status = stc$active THEN
            members_active_on_set := TRUE;
            RETURN; {----->
          IFEND;
        IFEND;
      FOREND;
    IFEND;

  PROCEND stp$members_active_on_set;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$members_inactive_on_set', EJECT ??
*copy sth$members_inactive_on_set

  PROCEDURE [XDCL] stp$members_inactive_on_set
    (    ast_index: stt$ast_index;
     VAR members_inactive_on_set: boolean);

    VAR
      mel_index: stt$mel_index,
      p_member_entry_list: ^stt$member_entry_list;

    p_member_entry_list := stv$p_ast^ [ast_index].p_member_entry_list;
    members_inactive_on_set := FALSE;
    IF p_member_entry_list <> NIL THEN
      FOR mel_index := LOWERBOUND (p_member_entry_list^) TO UPPERBOUND (p_member_entry_list^) DO
        IF p_member_entry_list^ [mel_index].entry_type = stc$valid THEN
          IF p_member_entry_list^ [mel_index].member_volume_activity.volume_activity_status =
                stc$inactive THEN
            members_inactive_on_set := TRUE;
            RETURN; {----->
          IFEND;
        IFEND;
      FOREND;
    IFEND;

  PROCEND stp$members_inactive_on_set;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$members_on_set', EJECT ??
*copy sth$members_on_set

  PROCEDURE [XDCL, #GATE] stp$members_on_set
    (    ast_index: stt$ast_index;
     VAR members_on_set: boolean);

    VAR
      mel_index: stt$mel_index,
      p_member_entry_list: ^stt$member_entry_list;

    p_member_entry_list := stv$p_ast^ [ast_index].p_member_entry_list;
    members_on_set := FALSE;
    IF p_member_entry_list <> NIL THEN
      FOR mel_index := LOWERBOUND (p_member_entry_list^) TO UPPERBOUND (p_member_entry_list^) DO
        IF p_member_entry_list^ [mel_index].entry_type = stc$valid THEN
          members_on_set := TRUE;
          RETURN; {----->
        IFEND;
      FOREND;
    IFEND;

  PROCEND stp$members_on_set;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$obtain_ast_entry', EJECT ??
*copy sth$obtain_ast_entry

  PROCEDURE [XDCL, #GATE] stp$obtain_ast_entry
    (    ast_index: stt$ast_index;
     VAR ast_entry: stt$active_set_entry;
     VAR status: ost$status);

    IF (stv$p_ast = NIL) OR (ast_index > UPPERBOUND (stv$p_ast^)) THEN
      osp$set_status_abnormal (stc$set_management_id, ste$set_not_active, stc$null_parameter, status);
    ELSE
      status.normal := TRUE;
      ast_entry := stv$p_ast^ [ast_index];
    IFEND;

  PROCEND stp$obtain_ast_entry;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$obtain_ast_pf_root', EJECT ??
*copy sth$obtain_ast_pf_root

  PROCEDURE [XDCL, #GATE] stp$obtain_ast_pf_root
    (    ast_index: stt$ast_index;
     VAR pf_root_container: pft$root;
     VAR status: ost$status);

    VAR
      entry_p: ^stt$active_set_entry,
      input_root_size: pft$root_size,
      p_pf_root: ^pft$root,
      p_pf_root_container: ^pft$root;

    entry_p := ^stv$p_ast^ [ast_index];
    IF entry_p^.pf_root_ever_stored AND (entry_p^.p_pf_root <> NIL) THEN
      input_root_size := #SIZE (pf_root_container);
      IF input_root_size < entry_p^.pf_root_size THEN
        osp$set_status_abnormal (stc$set_management_id, ste$incorrect_root_size, entry_p^.set_name, status);
      ELSE
        status.normal := TRUE;
        p_pf_root_container := ^pf_root_container;
        RESET p_pf_root_container;
        NEXT p_pf_root: [[REP entry_p^.pf_root_size OF cell]] IN p_pf_root_container;
        p_pf_root^ := entry_p^.p_pf_root^;
      IFEND;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$pf_root_not_stored, entry_p^.set_name, status);
    IFEND;

  PROCEND stp$obtain_ast_pf_root;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$obtain_ast_size', EJECT ??
*copy sth$obtain_ast_size

  PROCEDURE [XDCL, #GATE] stp$obtain_ast_size
    (VAR ast_size: integer);

    IF stv$p_ast = NIL THEN
      ast_size := 0;
    ELSE
      ast_size := UPPERBOUND (stv$p_ast^);
    IFEND;

  PROCEND stp$obtain_ast_size;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$search_ast_by_internal_vsn', EJECT ??

  PROCEDURE [XDCL, #GATE] stp$search_ast_by_internal_vsn
    (    volume: dmt$internal_vsn;
     VAR ast_entry: stt$active_set_entry;
     VAR ast_index: stt$ast_index;
     VAR volume_found: boolean);

    VAR
      mel_index: stt$mel_index,
      member_entry: stt$member_entry;

    volume_found := FALSE;
    IF stv$p_ast <> NIL THEN

    /search_for_volume/
      FOR ast_index := 1 TO UPPERBOUND (stv$p_ast^) DO
        ast_entry := stv$p_ast^ [ast_index];
        IF ast_entry.entry_type = stc$valid THEN
          IF ast_entry.master_internal_vsn = volume THEN
            volume_found := TRUE;
            EXIT /search_for_volume/; {----->
          ELSE
            stp$search_mel_for_internal_vol (volume, ast_index, member_entry, mel_index, volume_found);
            IF volume_found THEN
              EXIT /search_for_volume/; {----->
            IFEND;
          IFEND;
        IFEND;
      FOREND /search_for_volume/;
    IFEND;

  PROCEND stp$search_ast_by_internal_vsn;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$search_ast_by_set', EJECT ??
*copy sth$search_ast_by_set

  PROCEDURE [XDCL, #GATE] stp$search_ast_by_set
    (    set_name_key: stt$set_name;
     VAR found_ast_entry: stt$active_set_entry;
     VAR found_ast_index: stt$ast_index;
     VAR set_key_found: boolean);

    VAR
      upper: stt$ast_index;

    set_key_found := FALSE;
    IF stv$p_ast <> NIL THEN
      found_ast_index := 1;
      upper := UPPERBOUND (stv$p_ast^);
      WHILE found_ast_index <= upper DO
        IF (stv$p_ast^ [found_ast_index].entry_type = stc$valid)
{     } AND (stv$p_ast^ [found_ast_index].set_name = set_name_key) THEN
          set_key_found := TRUE;
          found_ast_entry := stv$p_ast^ [found_ast_index];
          RETURN; {----->
        ELSE
          found_ast_index := found_ast_index + 1;
        IFEND;
      WHILEND;
    IFEND;

  PROCEND stp$search_ast_by_set;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$search_ast_by_unique_set', EJECT ??
*copy sth$search_ast_by_unique_set

  PROCEDURE [XDCL, #GATE] stp$search_ast_by_unique_set
    (    unique_set_key: stt$unique_set_name;
     VAR found_ast_entry: stt$active_set_entry;
     VAR found_ast_index: stt$ast_index;
     VAR set_key_found: boolean);

    VAR
      upper: stt$ast_index;

    set_key_found := FALSE;
    IF stv$p_ast <> NIL THEN
      found_ast_index := 1;
      upper := UPPERBOUND (stv$p_ast^);
      WHILE found_ast_index <= upper DO
        IF (stv$p_ast^ [found_ast_index].entry_type = stc$valid)
{     } AND (stv$p_ast^ [found_ast_index].unique_set_name = unique_set_key) THEN
          set_key_found := TRUE;
          found_ast_entry := stv$p_ast^ [found_ast_index];
          RETURN; {----->
        ELSE
          found_ast_index := found_ast_index + 1;
        IFEND;
      WHILEND;
    IFEND;

  PROCEND stp$search_ast_by_unique_set;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$seach_ast_by_volume', EJECT ??
*copy sth$search_ast_by_volume

  PROCEDURE [XDCL] stp$search_ast_by_volume
    (    volume: rmt$recorded_vsn;
     VAR ast_entry: stt$active_set_entry;
     VAR ast_index: stt$ast_index;
     VAR volume_found: boolean);

    VAR
      mel_index: stt$mel_index,
      member_entry: stt$member_entry;

    volume_found := FALSE;
    IF stv$p_ast <> NIL THEN

    /search_for_volume/
      FOR ast_index := 1 TO UPPERBOUND (stv$p_ast^) DO
        ast_entry := stv$p_ast^ [ast_index];
        IF ast_entry.entry_type = stc$valid THEN
          IF ast_entry.master_vsn = volume THEN
            volume_found := TRUE;
            EXIT /search_for_volume/; {----->
          ELSE
            stp$search_mel_for_vol (volume, ast_index, member_entry, mel_index, volume_found);
            IF volume_found THEN
              EXIT /search_for_volume/; {----->
            IFEND;
          IFEND;
        IFEND;
      FOREND /search_for_volume/;
    IFEND;

  PROCEND stp$search_ast_by_volume;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$search_mel_for_internal_vol', EJECT ??

  PROCEDURE [XDCL] stp$search_mel_for_internal_vol
    (    member_vol: dmt$internal_vsn;
         ast_index: stt$ast_index;
     VAR member_entry: stt$member_entry;
     VAR mel_index: stt$mel_index;
     VAR volume_found: boolean);

    VAR
      p_mel: ^stt$member_entry_list;

    volume_found := FALSE;
    p_mel := stv$p_ast^ [ast_index].p_member_entry_list;
    IF p_mel <> NIL THEN
      FOR mel_index := LOWERBOUND (p_mel^) TO UPPERBOUND (p_mel^) DO
        IF p_mel^ [mel_index].entry_type = stc$valid THEN
          IF p_mel^ [mel_index].member_internal_vsn = member_vol THEN
            member_entry := p_mel^ [mel_index];
            volume_found := TRUE;
            RETURN; {----->
          IFEND;
        IFEND;
      FOREND;
    IFEND;

  PROCEND stp$search_mel_for_internal_vol;
?? OLDTITLE ??
MODEND stm$read_ast_r1;
