static int countnodes(NODE *node) { if (node) { nodecount++; if (nodecount > maxnodes) { printf("Too many nodes found - exceeds total nodes %d\n", maxnodes); return 0; } if (node->member) { if (parent_of(member_of(node)) != node) printf("Bad node linkage\n"); countnodes(member_of(node)); } if (node->child) { if (parent_of(child_of(node)) != node) printf("Bad node linkage\n"); countnodes(child_of(node)); } if (node->brother) { if (parent_of(brother_of(node)) != parent_of(node)) printf("Bad node linkage\n"); countnodes(brother_of(node)); } } return 1; }
STATIC_ROUTINE void check_nid(PINO_DATABASE *dblist, NID *nid, int *count) { int bitnum = nid->node; if (!getbit(bitnum)) { NODE *node; NODE *descendent; nid_to_node(dblist, nid, node); if (count) (*count)++; setbit(bitnum); for (descendent = member_of(node); descendent; descendent = brother_of(descendent)) { NID nid; node_to_nid(dblist, descendent, (&nid)); check_nid(dblist, &nid, count); } for (descendent = child_of(node); descendent; descendent = brother_of(descendent)) { NID nid; node_to_nid(dblist, descendent, (&nid)); check_nid(dblist, &nid, count); } if (swapshort((char *)&node->conglomerate_elt)) { NID elt_nid; NODE *elt_node; unsigned short elt_num = 1; elt_nid.node = nid->node - swapshort((char *)&node->conglomerate_elt) + 1; elt_nid.tree = nid->tree; nid_to_node(dblist, (&elt_nid), elt_node); for (; swapshort((char *)&elt_node->conglomerate_elt) == elt_num; elt_nid.node++, elt_num++, elt_node++) check_nid(dblist, &elt_nid, count); } } }
int SetParentState(PINO_DATABASE *db, NODE *node, unsigned int state) { int status; NCI nci; NODE *lnode; status = TreeNORMAL; for (lnode = node; lnode && (status & 1); lnode = brother_of(lnode)) { status = SetNodeParentState(db, lnode, &nci, state); if ((status & 1) && (!(nci.flags & NciM_STATE)) && (lnode->INFO.TREE_INFO.child)) status = SetParentState(db, child_of(lnode), state); if ((status & 1) && (!(nci.flags & NciM_STATE)) && (lnode->INFO.TREE_INFO.member)) status = SetParentState(db, member_of(lnode), state); } return status; }
extern void _TreeDeleteNodeExecute(void *dbid) { PINO_DATABASE *dblist = (PINO_DATABASE *)dbid; static NID nid; NODE *node; NODE *prevnode = 0; NODE *parent; static NCI empty_nci; NODE *firstempty = (dblist->tree_info->header->free == -1) ? (NODE *) 0 : (NODE *) ((char *) dblist->tree_info->node + dblist->tree_info->header->free); TREE_EDIT *edit = dblist->tree_info->edit; static int zero = 0; /*------------------------------------------------------------------------------ Executable: */ nid.tree = 0; nid.node = 0; while (_TreeDeleteNodeGetNid(dbid, (int*)&nid) & 1) { int found = 0; _TreeRemoveNodesTags(dbid, *(int *)&nid); _TreeSetNoSubtree(dbid, *(int *)&nid); nid_to_node(dblist, (&nid), node); parent = parent_of(node); if (child_of(parent) == node) { found = 1; if (node->INFO.TREE_INFO.brother) { link_it(parent->INFO.TREE_INFO.child,brother_of(node),parent); } else parent->INFO.TREE_INFO.child = 0; } else if (parent->INFO.TREE_INFO.child) { NODE *bro; for (bro = child_of(parent); bro->INFO.TREE_INFO.brother && (brother_of(bro) != node); bro = brother_of(bro)); if (brother_of(bro) == node) { found = 1; if (node->INFO.TREE_INFO.brother) { link_it(bro->INFO.TREE_INFO.brother,brother_of(node),bro); } else bro->INFO.TREE_INFO.brother = 0; } } if (!found) { if (member_of(parent) == node) { if (node->INFO.TREE_INFO.brother) { link_it(parent->INFO.TREE_INFO.member,brother_of(node), parent); } else parent->INFO.TREE_INFO.member = 0; } else if (parent->INFO.TREE_INFO.member) { NODE *bro; for (bro = member_of(parent); bro->INFO.TREE_INFO.brother && (brother_of(bro) != node); bro = brother_of(bro)); if (brother_of(bro) == node) { found = 1; if (node->INFO.TREE_INFO.brother) { link_it(bro->INFO.TREE_INFO.brother,brother_of(node), bro); } else bro->INFO.TREE_INFO.brother = 0; } } } if ((int)nid.node < edit->first_in_mem) { NCI old_nci; int nidx = nid.node; TreeGetNciLw(dblist->tree_info, nidx, &old_nci); TreePutNci(dblist->tree_info, nidx, &empty_nci, 1); } else memcpy(edit->nci + nid.node - edit->first_in_mem, &empty_nci, sizeof(struct nci)); memcpy(node->name,"deleted node",sizeof(node->name)); LoadShort(zero,&node->conglomerate_elt); node->INFO.TREE_INFO.member = 0; node->INFO.TREE_INFO.brother = 0; node->usage = 0; if (prevnode) { int tmp; link_it(prevnode->parent, node, prevnode); tmp = -swapint((char *)&prevnode->parent); node->INFO.TREE_INFO.child = swapint((char *)&tmp); } else { int tmp; link_it(tmp,node, dblist->tree_info->node); dblist->tree_info->header->free = swapint((char *)&tmp); node->INFO.TREE_INFO.child = 0; } if (firstempty) { int tmp; link_it(node->parent, firstempty, node); tmp = -swapint((char *)&node->parent); firstempty->INFO.TREE_INFO.child = swapint((char *)&tmp); } else node->parent = 0; prevnode = node; } dblist->modified = 1; _TreeDeleteNodeInitialize(dbid, 0, 0, 1); }