// insert new node to RPlus tree public virtual void insert(MBR obj) { Split_info sp; node tmp; MBR mbr; sp = new Split_info(); tmp = new node(); // must insert data object in somewhere in RPlus tree // ignore number of nodes inserted if (this.head == null) { this.head = new node(); } sp = this.head.insert_obj(obj, this.fillfactor); if (sp.newnode != null) { mbr = new MBR(sp.mbr); tmp.insert(mbr); tmp.head.child = sp.newnode; if (sp.xcut >= 0 && (tmp.head.current.cutxl == - 1 || sp.xcut > tmp.head.current.cutxl)) tmp.head.current.cutxl = sp.xcut; if (sp.ycut >= 0 && (tmp.head.current.cutyl == - 1 || sp.ycut > tmp.head.current.cutyl)) tmp.head.current.cutyl = sp.ycut; if (tmp.head.child != null) tmp.head.child.parent = tmp.head; tmp.head.resize(); mbr = new MBR(sp.mbr2); tmp.insert(mbr); tmp.head.child = head; if (sp.xcut >= 0 && (tmp.head.current.cutxh == - 1 || sp.xcut < tmp.head.current.cutxh)) tmp.head.current.cutxh = sp.xcut; if (sp.ycut >= 0 && (tmp.head.current.cutyh == - 1 || sp.ycut < tmp.head.current.cutyh)) tmp.head.current.cutyh = sp.ycut; if (tmp.head.child != null) tmp.head.child.parent = tmp.head; tmp.head.resize(); this.head = tmp; } }
// 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; }
// insert new node to subtree of this node // return number of nodes inserted internal virtual Split_info insert_obj(MBR obj, int fillfactor) { int counter = 0; // number of nodes inserted Split_info sp; CELL tmp; MBR tmpmbr; sp = new Split_info(); // try to insert data object to children for (CELL curr_cell = head; curr_cell != null; curr_cell = curr_cell.next) { // check children for overlapping with data object if (curr_cell.current.check_overlap(obj.mbr) == 1 && curr_cell.current.oid == 0) { // check if curr_cell is data cell if (curr_cell.child != null) { // non-data node // insert into subtree sp = curr_cell.child.insert_obj(obj, fillfactor); if (sp.newnode != null) { curr_cell.current.mbr = sp.mbr2; if (sp.xcut >= 0 && (curr_cell.current.cutxh == - 1 || sp.xcut < curr_cell.current.cutxh)) curr_cell.current.cutxh = sp.xcut; if (sp.ycut >= 0 && (curr_cell.current.cutyh == - 1 || sp.ycut < curr_cell.current.cutyh)) curr_cell.current.cutyh = sp.ycut; curr_cell.resize(); tmpmbr = new MBR(sp.mbr); this.insert(tmpmbr); this.head.child = sp.newnode; this.head.child.parent = this.head; this.head.current.cutxl = sp.cutxl; this.head.current.cutyl = sp.cutyl; this.head.current.cutxh = sp.cutxh; this.head.current.cutyh = sp.cutyh; if (sp.xcut >= 0 && (this.head.current.cutxl == - 1 || sp.xcut > this.head.current.cutxl)) this.head.current.cutxl = sp.xcut; if (sp.ycut >= 0 && (this.head.current.cutyl == - 1 || sp.ycut > this.head.current.cutyl)) this.head.current.cutyl = sp.ycut; this.head.resize(); } else { curr_cell.resize(); } counter++; } } } sp = new Split_info(); if (counter == 0) { // attach new child to this node attach(obj); } if (this.getlength() > fillfactor) { sp = this.splitnode(fillfactor); } if (this.parent != null) { this.parent.resize(); } return sp; }