/* Program Name : DIRECTQUE.C */ /* Original Author : C. K. Hung */ /* Date : 24-SEP-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ /* **** INCLUDE FILES *** */ #include "global.h" #include "direct.h" #include "filerenc.h" #include "directque.h" #include "dx.h" #include /* **** INTERNAL FUNCTION PROTOTYPING *** */ static struct node_tag * search_queue_node(struct node_tag *, char *); static int free_root_equ(struct root_equ_names_tag **); static int insert_root_equ_name( struct root_equ_names_tag **, char *); static int cmp_root_equ( struct root_equ_names_tag *, struct root_equ_names_tag *); /* ** FUNCTIONAL DESCRIPTION: ** */ int initialize_direct_cache() { int i; for (i = 0; i < MAX_DIRECT_BUFFER; i++) { convert_date_string ( "17-NOV-1858 00:00:00.00", &direct_cache[i].time_stamp); direct_cache[i].root_equ_names = (struct root_equ_names_tag *)NULL; direct_cache[i].direction = advance; strcpy(direct_cache[i].pattern, "[]"); direct_cache[i].root = (struct node_tag *)NULL; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** find_LRU_in_direct_cache() find the Least-Recently-Used slot ** in the directory cache. ** **-- **/ int find_LRU_in_direct_cache() { DATE_TIME earliest_time, cmp; int m, n; m = 0; memcpy (&earliest_time, &direct_cache[0].time_stamp, 8); for (n = 1; n < MAX_DIRECT_BUFFER; n++) { if (lib$sub_times( &direct_cache[n].time_stamp, &earliest_time, &cmp) == LIB$_NEGTIM) { memcpy( &earliest_time, &direct_cache[n].time_stamp, 8); m = n; } } /* ** Reset the default values and free up memory used by this node **/ direct_cache[m].direction = advance; strcpy(direct_cache[m].pattern, "[]"); free_root_equ (&(direct_cache[m].root_equ_names)); direct_cache[m].root_equ_names = (struct root_equ_names_tag *)NULL; free_dirtree (&(direct_cache[m].root), (struct node_tag *)NULL); direct_cache[m].root = (struct node_tag *)NULL; return m; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int search_direct_cache(n) char *n; { static _align (QUADWORD) int logicalQ[2]; struct logical_queue_entry_tag *E; unsigned long int status; int number_of_bytes; char *cp; int i; struct root_equ_names_tag *l; /* ** Translate the root logical name. **/ l = (struct root_equ_names_tag *)NULL; logicalQ[0] = logicalQ[1] = 0; trnlnm(n, logicalQ); while (_REMQHI (logicalQ, &E) != 3) { number_of_bytes = strlen(E->equivalent_name)+1; if ((cp = strstr (E->equivalent_name, ".000000]")) != NULL) { *cp++ = ']'; *cp = EOS; } insert_root_equ_name(&l, E->equivalent_name); check_OK(lib$free_vm ( &number_of_bytes, &E->equivalent_name, 0)) } for (i = 0; i < MAX_DIRECT_BUFFER; i++) { if (cmp_root_equ(l, direct_cache[i].root_equ_names)) { free_root_equ(&l); return i; } } free_root_equ(&l); return -1; /** Not found **/ } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int save_to_direct_cache(i, r, d, p, n) int i; char *r; enum directions d; char *p; struct node_tag *n; { static _align (QUADWORD) int logicalQ[2]; struct logical_queue_entry_tag *E; unsigned long int status; int number_of_bytes; char *cp; check_OK(sys$gettim ( /** Time stamp **/ &direct_cache[i].time_stamp)) /* ** Translate the root logical name. ** Should only expand to a single name. **/ direct_cache[i].root_equ_names = (struct root_equ_names_tag *)NULL; logicalQ[0] = logicalQ[1] = 0; trnlnm(r, logicalQ); while (_REMQHI (logicalQ, &E) != 3) { number_of_bytes = strlen(E->equivalent_name)+1; if ((cp = strstr (E->equivalent_name, ".000000]")) != NULL) { *cp++ = ']'; *cp = EOS; } insert_root_equ_name(&(direct_cache[i].root_equ_names), E->equivalent_name); check_OK(lib$free_vm ( &number_of_bytes, &E->equivalent_name, 0)) } direct_cache[i].direction = d; strcpy(direct_cache[i].pattern, p); direct_cache[i].root = n; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int restore_from_direct_cache(i, d, p, n) int i; enum directions *d; char *p; struct node_tag **n; { *d = direct_cache[i].direction; strcpy(p, direct_cache[i].pattern); *n = direct_cache[i].root; return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int add_to_direct_cache(e, errmsg) char *e; char *errmsg; { static _align (QUADWORD) int logicalQ[2]; struct logical_queue_entry_tag *E; unsigned long int status; int number_of_bytes; char *cp; int i; char f[MAXFILESPEC+1]; int len; char s1[MAXFILESPEC+1], s2[MAXFILESPEC+1]; int allocate_size = sizeof (struct node_tag); struct root_equ_names_tag *p; /* ** Translate the logical name. ** Should only expand to a single name. **/ logicalQ[0] = logicalQ[1] = 0; trnlnm(e, logicalQ); while (_REMQHI (logicalQ, &E) != 3) { number_of_bytes = strlen(E->equivalent_name)+1; if ((cp = strstr (E->equivalent_name, ".000000]")) != NULL) { *cp++ = ']'; *cp = EOS; } strcpy(f, E->equivalent_name); check_OK(lib$free_vm ( &number_of_bytes, &E->equivalent_name, 0)) } /* ** Search queue for insertion. **/ for (i = 0; i < MAX_DIRECT_BUFFER; i++) { /** Compare device and root name **/ for (p = direct_cache[i].root_equ_names; p != (struct root_equ_names_tag *)NULL; p = p->next) { strcpy(s1, p->equ_name); s1[ strlen(s1)-1 ] = EOS; /** Delete ']' **/ if (strstr (f, s1)) { break; /** Root is an ancestor **/ } } if (p != (struct root_equ_names_tag *)NULL) { /* ** Insert the newly created directory into the tree **/ if (add_node( &direct_cache[i].root, f, (struct node_tag *)NULL) == DX__ERROR) { return DX__ERROR; } /* ** Rebuild the directory tree **/ traverse_tree( direct_cache[i].root, (struct node_tag *)NULL, 1, 1, dummy); } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int delete_from_direct_cache(e, errmsg) char *e; char *errmsg; { static _align (QUADWORD) int logicalQ[2]; struct logical_queue_entry_tag *E; unsigned long int status; int number_of_bytes; char *cp; int i; char f[MAXFILESPEC+1]; struct node_tag *current, *downnode, *upnode, *leftnode, *rightnode; int len; char s1[MAXFILESPEC+1], s2[MAXFILESPEC+1]; int allocate_size = sizeof (struct node_tag); struct root_equ_names_tag *p; /* ** Translate the logical name. ** Should only expand to a single name. **/ logicalQ[0] = logicalQ[1] = 0; trnlnm(e, logicalQ); while (_REMQHI (logicalQ, &E) != 3) { number_of_bytes = strlen(E->equivalent_name)+1; if ((cp = strstr (E->equivalent_name, ".000000]")) != NULL) { *cp++ = ']'; *cp = EOS; } strcpy(f, E->equivalent_name); check_OK(lib$free_vm ( &number_of_bytes, &E->equivalent_name, 0)) } /* ** Search queue for deletion. **/ for (i = 0; i < MAX_DIRECT_BUFFER; i++) { for (p = direct_cache[i].root_equ_names; p != (struct root_equ_names_tag *)NULL; p = p->next) { strcpy(s1, p->equ_name); s1[ strlen(s1)-1 ] = EOS; /** Delete ']' **/ if (strstr (f, s1)) { break; /** Root is an ancestor **/ } } if (p != (struct root_equ_names_tag *)NULL) { if ((current = search_queue_node(direct_cache[i].root, f)) != NULL) { /** Re-link UP node **/ if ((upnode = current->up) != (struct node *)NULL) upnode->down = current->down; /** Re-link DOWN node **/ if ((downnode = current->down) != (struct node *)NULL) downnode->up = upnode; /* ** Re-link RIGHT node if the node deleted was the ** first child **/ leftnode = current->left; if (leftnode->right == current) { /** This is the oldest child **/ if (current->down == NULL) /** No more child **/ leftnode->right = (struct node *)NULL; else if (leftnode == downnode->left) /** Same parent **/ leftnode->right = downnode; else leftnode->right = (struct node *)NULL; } /** Free up memory allocated to this node **/ lib$free_vm ( &allocate_size, ¤t, 0); } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static struct node_tag * search_queue_node(n, f) struct node_tag *n; char *f; { struct fil_dx_tag st; struct node_tag *m; char errmsg[MAXFILESPEC+1]; if (n == (struct node_tag *)NULL) { return (struct node_tag *)NULL; } else if (!strcmp(n->full_path_name, f)) { return n; } else if ((m = search_queue_node(n->right, f)) != (struct node_tag *)NULL) { return m; } else if (n->down->left == n->left) { return search_queue_node(n->down, f); } else { return (struct node_tag *)NULL; } } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int free_root_equ(r) struct root_equ_names_tag **r; { int node_entry_size = sizeof (struct root_equ_names_tag); if (*r != (struct root_equ_names_tag *)NULL) { free_root_equ(&((*r)->next)); check_OK(lib$free_vm ( &node_entry_size, r, 0)) *r = (struct root_equ_names_tag *)NULL; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int insert_root_equ_name(r, name) struct root_equ_names_tag **r; char *name; { int allocate_size = sizeof (struct root_equ_names_tag); struct root_equ_names_tag *new; if (*r != (struct root_equ_names_tag *)NULL) { insert_root_equ_name(&((*r)->next), name); } else { check_OK(lib$get_vm ( &allocate_size, &new, 0)) strcpy(new->equ_name, name); new->next = (struct root_equ_names_tag *)NULL; *r = new; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int cmp_root_equ(s, t) struct root_equ_names_tag *s, *t; { struct root_equ_names_tag *p, *q; for (p = s; p != (struct root_equ_names_tag *)NULL; p = p->next) { for (q = t; q != (struct root_equ_names_tag *)NULL; q = q->next) { if (!strcmp(p->equ_name, q->equ_name)) { break; } } if (q == (struct root_equ_names_tag *)NULL) { return 0; /** Not found **/ } } for (p = t; p != (struct root_equ_names_tag *)NULL; p = p->next) { for (q = s; q != (struct root_equ_names_tag *)NULL; q = q->next) { if (!strcmp(p->equ_name, q->equ_name)) { break; } } if (q == (struct root_equ_names_tag *)NULL) { return 0; /** Not found **/ } } return 1; /** Same list **/ }