turbo_index.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 1,015 行 · 第 1/2 页
C
1,015 行
/* a return of OK means it was the first one inserted */ if ( avl_insert( &pindex[ i ].i_root, (caddr_t) imem, index_cmp, index_dup ) == OK ) { pindex[ i ].i_count++; imem = NULLINDEXNODE; } else if ( substr ) { save = AttrV_cpy( &av->avseq_av ); savestr = (char *) save->av_struct; save->av_struct = strrev( savestr ); AttrV_free( (AttributeValue) imem->in_value ); free( savestr ); imem->in_value = (caddr_t) save; } else { AttrV_free( (AttributeValue) imem->in_value ); free( (char *) imem->in_entries ); free( (char *) imem ); } if ( substr && imem == NULLINDEXNODE ) { imem = (Index_node *) malloc( sizeof(Index_node) ); save = AttrV_cpy( &av->avseq_av ); savestr = (char *) save->av_struct; save->av_struct = strrev( savestr ); free( savestr ); imem->in_value = (caddr_t) save; imem->in_entries = (struct entry **) malloc( sizeof(struct entry *) ); imem->in_entries[ 0 ] = (struct entry *) e; imem->in_num = 1; imem->in_max = 1; } /* insert into the reverse index, if appropriate */ if ( substr ) { if ( avl_insert( &pindex[ i ].i_rroot, (caddr_t) imem, index_cmp, index_dup ) == OK ) { pindex[ i ].i_rcount++; imem = NULLINDEXNODE; } else { AttrV_free( (AttributeValue) imem->in_value ); free( (char *) imem->in_entries ); free( (char *) imem ); } } if ( approxfn( attr->oa_syntax ) != soundex_match ) continue; for ( word = first_word((char *) av->avseq_av.av_struct); word; word = next_word( word ) ) { code = NULL; soundex( word, &code ); imem = (Index_node *) malloc( sizeof(Index_node) ); imem->in_value = (caddr_t) code; imem->in_entries = (struct entry **) malloc( sizeof(struct entry *) ); imem->in_entries[ 0 ] = (struct entry *) e; imem->in_num = 1; imem->in_max = 1; if ( avl_insert( &pindex[i].i_sroot, (caddr_t) imem, sindex_cmp, index_dup ) == OK ) { pindex[ i ].i_scount++; } else { free( (char *) imem->in_value ); free( (char *) imem->in_entries ); free( (char *) imem ); } } }}/* * turbo_add2index -- search through the given entry's attribute list for * attrs to optimize. if an attr to optimize is found, we add that attribute * along with a pointer to the corresponding entry to the appropriate * attribute index. */turbo_add2index( e )Entry e; /* the entry these attrs belong to */{ Entry parent; Attr_Sequence as, entry_find_type(); DN pdn, dn, tmpdn, prevdn, savedn; int pcmp, nonleaf; Index *subindex; Index *sibindex; extern AttributeType at_masterdsa, at_slavedsa; if ( sibling_index == (Avlnode *) 0 && subtree_index == (Avlnode *) 0 ) return; nonleaf = !e->e_leaf; parent = e->e_parent; pdn = get_copy_dn( parent ); dn = get_copy_dn( e ); sibindex = get_sibling_index( pdn ); /* for each attribute in the entry... */ for ( as = e->e_attributes; as != NULLATTR; as = as->attr_link ) { if ( turbo_isoptimized( as->attr_type ) == 0 ) continue; SET_HEAP( as->attr_type ); /* sibling index */ if ( sibindex ) { (void) turbo_attr_insert( sibindex, e, as->attr_type, as->attr_value ); } savedn = NULLDN; while ( dn->dn_parent != NULLDN ) { if ( subindex = get_subtree_index( dn ) ) { (void) turbo_attr_insert( subindex, e, as->attr_type, as->attr_value ); } for ( prevdn = NULLDN, tmpdn = dn; tmpdn->dn_parent != NULLDN; prevdn = tmpdn, tmpdn = tmpdn->dn_parent ) ; /* NULL */ tmpdn->dn_parent = savedn; savedn = tmpdn; prevdn->dn_parent = NULLDN; } dn->dn_parent = savedn; } RESTORE_HEAP; /* now add references in nonleafkids and nonlocalaliases... */ if ( sibindex ) if ( e->e_alias && th_prefix( sibindex->i_dn, e->e_alias ) != -2 ) add_nonlocalalias( e, sibindex ); if ( nonleaf == 0 && e->e_alias == NULLDN ) { dn_free( dn ); dn_free( pdn ); return; } /* could be a subtree index with all parents & this node */ savedn = NULLDN; while ( dn->dn_parent != NULLDN ) { if ( subindex = get_subtree_index( dn ) ) { if ( e->e_alias ) { pcmp = th_prefix( subindex->i_dn, e->e_alias ); if ( pcmp > 0 ) add_nonlocalalias(e, subindex); } if ( nonleaf ) add_nonleafkid(e, subindex); } for ( prevdn = NULLDN, tmpdn = dn; tmpdn->dn_parent != NULLDN; prevdn = tmpdn, tmpdn = tmpdn->dn_parent ) ; /* NULL */ tmpdn->dn_parent = savedn; savedn = tmpdn; prevdn->dn_parent = NULLDN; } dn->dn_parent = savedn; dn_free( dn ); dn_free( pdn ); return;}/* * turbo_attr_delete -- delete entry e from index for values of attribute * attr. */static turbo_attr_delete( pindex, e, attr, values )Index *pindex;Entry e;AttributeType attr;AV_Sequence values;{ int i, j, k; AV_Sequence av; Index_node *node, *imem; struct entry **p; char *code, *word; char *first_word(), *next_word(); /* find the appropriate index */ for ( i = 0; i < turbo_index_num; i++ ) if ( AttrT_cmp( pindex[ i ].i_attr, attr ) == 0 ) break; if ( i == turbo_index_num ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("turbo_attr_delete: cannot find optimized attribute") ); return; } /* delete all values */ for ( av = values; av != NULLAV; av = av->avseq_next ) { node = (Index_node *) avl_find( pindex[ i ].i_root, (caddr_t) &av->avseq_av, (IFP)indexav_cmp ); if ( node == NULLINDEXNODE ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("Optimized attribute value not found! (%s)\n", attr->oa_ot.ot_name) ); continue; } /* find the entry we want to delete */ p = node->in_entries; for ( j = 0; j < node->in_num; j++, p++ ) if ( *p == (struct entry *) e ) break; if ( j == node->in_num ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("Optimized av entry not found") ); continue; } if ( --(node->in_num) == 0 ) { imem = (Index_node *) avl_delete( &pindex[ i ].i_root, (caddr_t) &av->avseq_av, indexav_cmp ); ( void ) AttrV_free( (AttributeValue) imem->in_value ); ( void ) free( (char *) imem->in_entries ); ( void ) free( (char *) imem ); pindex[ i ].i_count--; } else { for ( k = j; k < node->in_num; k++ ) node->in_entries[ k ] = node->in_entries[ k + 1 ]; node->in_entries = (struct entry **) realloc( (char *) node->in_entries, (unsigned) node->in_num * sizeof(struct entry *) ); } /* if there's a soundex index, delete from that too */ if ( pindex[i].i_sroot == NULLAVL ) continue; for ( word = first_word((char *)av->avseq_av.av_struct); word != NULL; word = next_word( word ) ) { code = NULL; soundex( word, &code ); /* * not finding the node is ok if the entry happens * to be the only one with this code and was deleted * on a previous pass through this loop. we hope. */ if ((imem = (Index_node *) avl_find(pindex[i].i_sroot, code, index_soundex_cmp)) == NULLINDEXNODE) { free(code); continue; } /* find the entry */ p = imem->in_entries; for ( j = 0; j < imem->in_num; j++, p++ ) if ( *p == (struct entry *) e ) break; /* * not finding the entry is this is ok for the soundex * index since an entry can appear more than once and * might have already been deleted on a previous pass */ if ( j == imem->in_num ) continue; if ( --(imem->in_num) == 0 ) { imem = (Index_node *) avl_delete( &pindex[ i ].i_sroot, (caddr_t) code, index_soundex_cmp ); free( (char *) imem->in_value ); free( (char *) imem->in_entries ); free( (char *) imem ); } else { for ( k = j; k < imem->in_num; k++ ) imem->in_entries[ k ] = imem->in_entries[ k+1 ]; imem->in_entries = (struct entry **) realloc( (char *) imem->in_entries, (unsigned) imem->in_num * sizeof(struct entry *) ); } free(code); } }}/* * turbo_index_delete -- delete attribute index entries for the given * entry from the attribute index associated with the entry's parent * node. */turbo_index_delete( e )Entry e;{ Entry parent; Attr_Sequence as; DN pdn, dn, tmpdn, prevdn, savedn; Index *subindex; Index *sibindex; int pcmp, nonleaf; if ( subtree_index == NULLAVL && sibling_index == NULLAVL ) return; nonleaf = (! isleaf(e)); parent = e->e_parent; pdn = get_copy_dn( parent ); dn = get_copy_dn( e ); sibindex = get_sibling_index( pdn ); /* for each attribute in the entry... */ for ( as = e->e_attributes; as != NULLATTR; as = as->attr_link ) { if ( turbo_isoptimized( as->attr_type ) == 0 ) continue; /* sibling index */ if ( sibindex ) { (void) turbo_attr_delete( sibindex, e, as->attr_type, as->attr_value ); } savedn = NULLDN; while ( dn->dn_parent != NULLDN ) { if ( subindex = get_subtree_index( dn ) ) { (void) turbo_attr_delete( subindex, e, as->attr_type, as->attr_value ); } for ( prevdn = NULLDN, tmpdn = dn; tmpdn->dn_parent != NULLDN; prevdn = tmpdn, tmpdn = tmpdn->dn_parent ) ; /* NULL */ tmpdn->dn_parent = savedn; savedn = tmpdn; prevdn->dn_parent = NULLDN; } dn->dn_parent = savedn; } /* now delete references in nonleafkids and nonlocalaliases... */ if ( sibindex && e->e_alias && th_prefix( sibindex->i_dn, e->e_alias ) != -2 ) delete_nonlocalalias( e, sibindex ); if ( nonleaf == 0 && e->e_alias == NULLDN ) { dn_free( pdn ); dn_free( dn ); return; } /* could be a subtree index with all parents & this node */ savedn = NULLDN; while ( dn->dn_parent != NULLDN ) { if ( subindex = get_subtree_index( dn ) ) { if ( e->e_alias ) { pcmp = th_prefix( subindex->i_dn, e->e_alias ); if ( pcmp > 0 ) delete_nonlocalalias( e, subindex ); } if ( nonleaf ) delete_nonleafkid( e, subindex ); } for ( prevdn = NULLDN, tmpdn = dn; tmpdn->dn_parent != NULLDN; prevdn = tmpdn, tmpdn = tmpdn->dn_parent ) ; /* NULL */ tmpdn->dn_parent = savedn; savedn = tmpdn; prevdn->dn_parent = NULLDN; } dn->dn_parent = savedn; dn_free( pdn ); dn_free( dn ); return;}/* * turbo_isoptimized -- return TRUE if attr is to be optimized, FALSE * otherwise. */turbo_isoptimized( attr )AttributeType attr;{ int i; for ( i = 0; i < turbo_index_num; i++ ) { if ( AttrT_cmp( attr, turbo_index_types[ i ] ) == 0 ) return( 1 ); } return( 0 );}/* * turbo_optimize -- add attribute attr to the list of attributes to be * optimized this routine creates an empty index and arranges for the * attribute to be optimized during loading. */turbo_optimize( attr )char *attr;{ AttributeType a; if ( (a = str2AttrT( attr )) == NULLAttrT ) { LLOG(log_dsap, LLOG_EXCEPTIONS, ("Bad attribute type (%s)", attr)); return; } if ( subtree_index || sibling_index ) fatal( -99, "optimized attributes MUST be specified before subtree or sibling index" ); if ( turbo_index_types == (AttributeType *) 0 ) turbo_index_types = (AttributeType *) malloc( sizeof(AttributeType *)); else turbo_index_types = (AttributeType *) realloc( (char *) turbo_index_types, (unsigned) (turbo_index_num + 1) * sizeof(AttributeType *)); if ( turbo_index_types == (AttributeType *) 0 ) fatal(66, "turbo_optimize: malloc failed!\n"); turbo_index_types[ turbo_index_num ] = AttrT_cpy(a); turbo_index_num++; return;}/* * index_subtree - arrange for the subtree starting at tree to be indexed. */index_subtree( tree )char *tree;{ DN dn, str2dn(); Index *pindex; if ( (dn = str2dn( tree )) == NULLDN ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("Invalid subtree (%s)\n", tree) ); return; } if ( turbo_index_num == 0 ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("WARNING: cannot index subtree - no attributes have been optimized")); return; } pindex = new_index( dn ); dn_free( dn ); if ( avl_insert( &subtree_index, (caddr_t) pindex, i_cmp, i_dup ) == NOTOK ) { LLOG(log_dsap, LLOG_EXCEPTIONS, ("Subtree index for %s already exists\n", tree)); index_free( pindex ); } return;}/* * index_siblings - arrange for the children of parent to be indexed. */index_siblings( parent )char *parent;{ DN dn, str2dn(); Index *pindex; if ( (dn = str2dn( parent )) == NULLDN ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("Invalid parent (%s)\n", parent) ); return; } if ( turbo_index_num == 0 ) { LLOG( log_dsap, LLOG_EXCEPTIONS, ("WARNING: cannot index siblings - no attributes have been optimized")); return; } pindex = new_index( dn ); dn_free( dn ); if ( avl_insert( &sibling_index, (caddr_t) pindex, i_cmp, i_dup ) == NOTOK ) { LLOG(log_dsap, LLOG_EXCEPTIONS, ("Sibling index for %s already exists\n", parent)); index_free( pindex ); } return;}#endif /* turbo_index */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?