// Split the called node. "this" object points to one node, return the new node created internal virtual Split_info splitnode(int fillfactor, Cut_info input_cut) { return redistribute_node(fillfactor, input_cut); }
// Partition. return partition_info, a new node R and a list of // MBRs in S internal virtual Partition_info partition(node N, int fillfactor) { Partition_info result; Cut_info xsweep, ysweep; Cut_info select; CELL tmp, cur, cur_cell; result = new Partition_info(); result.R.parent = N.parent; if (N.getlength() <= fillfactor) { result.R.head = N.head; return result; } xsweep = N.sweep('x', fillfactor); ysweep = N.sweep('y', fillfactor); cur = new CELL(); select = new Cut_info(); if (xsweep.cost == - 1 && ysweep.cost == - 1) { System.Console.Out.WriteLine("ERROR : Cannot Split node!!"); System.Environment.Exit(1); } else if (xsweep.cost == - 1 || (xsweep.cost > ysweep.cost && ysweep.cost != - 1)) { select = ysweep; result.xy = 'y'; } else { select = xsweep; result.xy = 'x'; } // create the new node R cur = select.S1.head; while (cur != null) { cur_cell = new CELL(cur.current); // find the child node tmp = N.head; if (tmp != null) { while (tmp.current.mbr.low[0] != cur_cell.current.mbr.low[0] || tmp.current.mbr.low[1] != cur_cell.current.mbr.low[1] || tmp.current.mbr.high[0] != cur_cell.current.mbr.high[0] || tmp.current.mbr.high[1] != cur_cell.current.mbr.high[1]) { tmp = tmp.next; } cur_cell.child = tmp.child; cur_cell.current = tmp.current; // insert into the node if (result.R.head != null) { result.R.head.prev = cur_cell; cur_cell.next = result.R.head; } result.R.head = cur_cell; } cur = cur.next; } // create the list S cur = select.S2.head; while (cur != null) { cur_cell = new CELL(cur.current); cur_cell.child = cur.child; result.S.insertList(cur_cell); cur = cur.next; } if (result.xy == 'x') { result.xcut = select.cut; } else if (result.xy == 'y') { result.ycut = select.cut; } return result; }
// Function called by to redistribute nodes in the list // by Nelson internal virtual Split_info redistribute_node(int ff, Cut_info cut) { node tmp, tmp2; Split_info info, info2; MBR tmpmbr; CELL ptr; RECT R1, R2, ns1, ns2; RECT parent, par2; int check1, check2; info = new Split_info(); parent = new RECT(); if (this.parent != null) { parent.low[0] = this.parent.current.mbr.low[0]; parent.low[1] = this.parent.current.mbr.low[1]; parent.high[0] = this.parent.current.mbr.high[0]; parent.high[1] = this.parent.current.mbr.high[1]; } else { parent = this.getnodesize(); } par2 = this.getnodesize(); tmp = new node(); tmp2 = new node(); tmp.parent = this.parent; tmp2.parent = this.parent; if (cut.dir == 'x') { R1 = new RECT(parent.low[0], parent.low[1], cut.cut, parent.high[1]); R2 = new RECT(cut.cut, parent.low[1], parent.high[0], parent.high[1]); info.xcut = cut.cut; } else { R1 = new RECT(parent.low[0], parent.low[1], parent.high[0], cut.cut); R2 = new RECT(parent.low[0], cut.cut, parent.high[0], parent.high[1]); info.ycut = cut.cut; } ptr = this.head; while (ptr != null) { check1 = ptr.current.check_overlap(R1); check2 = ptr.current.check_overlap(R2); if (check1 == 1 && check2 != 1) { tmp.insert(ptr.current); tmp.head.child = ptr.child; if (tmp.head.child != null) tmp.head.child.parent = tmp.head; } else if (check1 != 1 && check2 == 1) { tmp2.insert(ptr.current); tmp2.head.child = ptr.child; if (tmp2.head.child != null) tmp2.head.child.parent = tmp2.head; } else { if (ptr.child != null) { info2 = ptr.child.splitnode(ff, cut); tmp.insert(ptr.current); tmp.head.child = ptr.child; tmp.head.child.parent = tmp.head; tmpmbr = new MBR(info2.mbr); tmp2.insert(tmpmbr); tmp2.head.child = info2.newnode; tmp2.head.child.parent = tmp2.head; } else { tmp.insert(ptr.current); tmp.head.child = ptr.child; tmp.parent = this.parent; tmp2.insert(ptr.current); tmp2.head.child = ptr.child; tmp2.parent = this.parent; } } ptr = ptr.next; } this.head = tmp.head; if (this.parent != null) { this.parent.current.mbr = R1; info.cutxl = this.parent.current.cutxl; info.cutyl = this.parent.current.cutyl; info.cutxh = this.parent.current.cutxh; info.cutyh = this.parent.current.cutyh; } info.mbr2 = R1; info.mbr = R2; info.newnode = tmp2; return info; }
// Sweep the called node. axis specifies // the axis for sweeping while ff specifies // the fill factor. internal virtual Cut_info sweep(char axis, int ff) { float curr_cost, min_cost; float curr_cut, min_cut; ; node new_node1 = new node(); node new_node2 = new node(); int len1, len2; Cut_info i; RECT pmbr; pmbr = new RECT(); if (this.parent != null) { pmbr = this.parent.current.mbr; } else { pmbr = this.getnodesize(); } min_cost = - 1f; min_cut = - 1f; // Split the cells, which are sorted in ascending order. curr_cut = split_cells(axis, 'a', ff, new_node1, new_node2); // Get the length of the two cell lists. len1 = new_node1.getlength(); len2 = new_node2.getlength(); if (len1 != 0) { // Evaluate the cost. curr_cost = evaluate(axis, new_node1, new_node2, curr_cut, pmbr); if (min_cost < 0) { min_cost = curr_cost; min_cut = curr_cut; } else if (curr_cost < min_cost) { min_cost = curr_cost; min_cut = curr_cut; } } i = new Cut_info(min_cost, min_cut, new_node1.head, new_node2.head); return (i); }