// 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; }
internal virtual node pack(node input, int fillfactor) { node result; Partition_info info; MBR mbr; RECT rect; float xcut = 0, ycut = 0; result = new node(); while (input.head != null) { info = new Partition_info(); info = this.partition(input, fillfactor); rect = new RECT(info.R.getnodesize()); mbr = new MBR(rect); result.insert(mbr); if (result.head.current.mbr.low[0] < xcut && xcut > 0) { result.head.current.mbr.low[0] = xcut; result.head.current.cutxl = xcut; } if (result.head.current.mbr.low[1] < ycut && ycut > 0) { result.head.current.mbr.low[1] = ycut; result.head.current.cutyl = ycut; } if (result.head.current.mbr.high[0] > info.xcut && info.xy == 'x') { result.head.current.mbr.high[0] = info.xcut; result.head.current.cutxh = info.xcut; } if (result.head.current.mbr.high[1] > info.ycut && info.xy == 'y') { result.head.current.mbr.high[1] = info.ycut; result.head.current.cutyh = info.ycut; } if (info.xy == 'x') { xcut = info.xcut; } if (info.xy == 'y') { ycut = info.ycut; } result.head.child = info.R; input.head = info.S.head; } if (result.getlength() <= fillfactor) { return result; } return this.pack(result, fillfactor); }