/**\brief Se fuciona con otra pagina*/ public void Fusionate(CNodo paginaB) { int i; for (i = 0; i < paginaB.getNumElemnt(); i++) { claves[getNumElemnt()] = paginaB.getAtClave(i); dirClaves[getNumElemnt()] = paginaB.getAtDirClaves(i); if(dir != paginaB.getAtDirNodo(i)) dirNodos[getNumElemnt()] = paginaB.getAtDirNodo(i); numElem++; } if (tipoNodo == 1 || tipoNodo == 4) dirNodos[getNumElemnt()] = paginaB.getAtDirNodo(i); }
/**Lee las claves primaria y las carga el el nodo del arbol */ public void leerClaves(CNodo nuevo) { for (int i = 0; i < nuevo.getNumElemnt(); i++) { br.BaseStream.Seek(nuevo.getAtDirClaves(i), SeekOrigin.Begin); switch (nuevo.getTipoClave()) { case 2://Short nuevo.setAtClave(i, br.ReadInt16()); break; case 3://Int nuevo.setAtClave(i, br.ReadInt32()); break; case 4://Float nuevo.setAtClave(i, br.ReadSingle()); break; case 5://Long nuevo.setAtClave(i, br.ReadInt64()); break; case 6://Double nuevo.setAtClave(i, br.ReadDouble()); break; case 7://Cadena nuevo.setAtClave(i, br.ReadString()); break; } } }
/**Escribe un objeto CNodo utilizado en Arbol B+*/ public void escribeNodo(CNodo nuevo) { bw.BaseStream.Seek(nuevo.getDir(), SeekOrigin.Begin); bw.Write(nuevo.getDir()); bw.Write(nuevo.getTipoNodo()); bw.Write(nuevo.getNumElemnt()); bw.Write(nuevo.getGrado()); bw.Write(nuevo.getTipoClave()); //Escribir la dir de las paginas u hojas for (int i = 0; i < (nuevo.getGrado() * 2) + 1; i++) bw.Write(nuevo.getAtDirNodo(i)); //Escribir la dir de las llaves de las paginas del arbol for (int i = 0; i < nuevo.getGrado() * 2; i++) bw.Write(nuevo.getAtDirClaves(i)); }
private void prestarClave(CNodo paginaAux, CNodo paginaA, CNodo paginaB, int i, int posB) { int index,posClave; long dirClave; Object clave; if (i == paginaAux.getNumElemnt()) { posClave = paginaB.getNumElemnt() - 1; index = 0; paginaA.setAtClave(index+1,paginaA.getAtClave(index)); paginaA.setAtDirClaves(index+1,paginaA.getAtDirClaves(index)); paginaA.setAtDirNodo(index+1,paginaA.getAtDirNodo(index)); } else { posClave = 0; index = 1; } paginaA.setAtClave(index, paginaB.getAtClave(posClave)); paginaA.setAtDirClaves(index, paginaB.getAtDirClaves(posClave)); paginaA.setAtDirNodo(index, paginaB.getAtDirNodo(posClave)); paginaA.incNumElem(); paginaB.eliminaClaveOrd(paginaB.getAtClave(posClave)); if (i < posB) { clave = paginaB.getAtClave(0); dirClave = paginaB.getAtDirClaves(0); posB--; } else { clave = paginaA.getAtClave(0); dirClave = paginaA.getAtDirClaves(0); } paginaAux.setAtClave(posB,clave); paginaAux.setAtDirClaves(posB,dirClave); }
/**Lee un nodo especifico que forma parte del arbol B+*/ public CNodo leerNodo(long pos) { CNodo nuevo = new CNodo(); br.BaseStream.Seek(pos, SeekOrigin.Begin); nuevo.setDir(br.ReadInt64()); nuevo.setTipoNodo(br.ReadInt32()); nuevo.setNumElemnt(br.ReadInt32()); nuevo.setGrado(br.ReadInt32()); nuevo.setTipoClave(br.ReadInt32()); nuevo.creaArrayDirNodos(nuevo.getGrado()); nuevo.creaArrayDirClaves(nuevo.getGrado()); nuevo.creaArrayClaves(nuevo.getGrado()); //Leer las direcciones de sus nodos descendientes for (int i = 0; i < (nuevo.getGrado() * 2) + 1; i++) nuevo.setAtDirNodo(i, br.ReadInt64()); //Leer las direciones de las claves del nodo( Hoja, pagina o Raiz ) for (int i = 0; i < nuevo.getGrado() * 2; i++) nuevo.setAtDirClaves(i, br.ReadInt64()); //Se leen las claves primarias y se almacenan en el vector de objectos leerClaves(nuevo); return (nuevo); }
/**Presta una clave a alguna nodo del arbol*/ public void prestarClavePagina(CNodo paginaAux, CNodo paginaA, CNodo paginaB, int i, int posB) { int posClave, posIns, posEliminado; Object clave; if (i < posB) { posClave = i; clave = paginaAux.getAtClave(i); posIns = paginaA.getNumElemnt(); posEliminado = 0; } else { posClave = posB; clave = paginaAux.getAtClave(posB); posIns = 0; posEliminado = paginaB.getNumElemnt()-1; } paginaA.insClaveOrd(clave, null, null, posIns); paginaA.setAtDirClaves(posIns, paginaAux.getAtDirClaves(posClave)); paginaAux.setAtClave(posClave, paginaB.getAtClave(posEliminado)); paginaAux.setAtDirClaves(posClave, paginaB.getAtDirClaves(posEliminado)); if (i < posB) { paginaA.setAtDirNodo(posIns + 1, paginaB.getAtDirNodo(0)); paginaB.eliminaClaveOrd(paginaB.getAtClave(0)); } else { paginaA.setAtDirNodo(1, paginaA.getAtDirNodo(0)); paginaA.setAtDirNodo(0, paginaB.getAtDirNodo(posEliminado+1)); paginaB.eliminaClaveOrd(paginaB.getAtClave(posEliminado)); } }
/**\brief Particiona un nodo del Arbol B+*/ public CNodo particiona(CNodo hoja, CBloque b, long posB, ref Object clave, ref long dirClave, int i) { CNodo nuevo = new CNodo(hoja.getTipoNodo(), GRADO); int k, j; Object claveAux = null; long dirAux = -1; if (hoja.getTipoNodo() == RAIZHOJA) { hoja.setTipoNodo(HOJA); nuevo.setTipoNodo(HOJA); } else if (hoja.getTipoNodo() == RAIZ) { hoja.setTipoNodo(PAGINA); nuevo.setTipoNodo(PAGINA); } nuevo.setTipoClave(b.getTipoCA()); j = (2 * GRADO) - 1; if (i >= GRADO) { if (hoja.getTipoNodo() == RAIZ || hoja.getTipoNodo() == PAGINA) { if (i == GRADO) { k = GRADO - 1; hoja.setNumElemnt(GRADO); claveAux = clave; dirAux = dirClave; } else { k = GRADO - 2; hoja.setNumElemnt(GRADO); claveAux = hoja.getAtClave(GRADO); dirAux = hoja.getAtDirClaves(GRADO); } } else { k = GRADO - 1; hoja.setNumElemnt(GRADO); } } else { if (hoja.getTipoNodo() == RAIZ || hoja.getTipoNodo() == PAGINA) { claveAux = hoja.getAtClave(GRADO - 1); dirAux = hoja.getAtDirClaves(GRADO - 1); k = GRADO - 1; } else k = GRADO; hoja.setNumElemnt(GRADO - 1); } nuevo.setNumElemnt(k + 1); for (; k >= 0; k--, j--) { nuevo.setAtClave(k, hoja.getAtClave(j)); nuevo.setAtDirClaves(k, hoja.getAtDirClaves(j)); if (hoja.getTipoNodo() == RAIZ || hoja.getTipoNodo() == PAGINA) nuevo.setAtDirNodo(k + 1, hoja.getAtDirNodo(j + 1)); else nuevo.setAtDirNodo(k, hoja.getAtDirNodo(j)); } if (i >= GRADO) { if (hoja.getTipoNodo() == RAIZ || hoja.getTipoNodo() == PAGINA) { if (i != GRADO) { nuevo.setAtDirNodo(0, hoja.getAtDirNodo(GRADO + 1)); nuevo.insClaveOrd(clave, b, getArchivo(), (i - GRADO) - 1); nuevo.setAtDirClaves((i - GRADO) - 1, dirClave); nuevo.setAtDirNodo(i - GRADO, posB); }else nuevo.setAtDirNodo(0, posB); } else nuevo.insClaveOrd(clave, b, getArchivo(), i - GRADO); } else { hoja.insClaveOrd(clave, b, getArchivo(), i); if (hoja.getTipoNodo() == RAIZ || hoja.getTipoNodo() == PAGINA) { nuevo.setAtDirNodo(0, hoja.getAtDirNodo(GRADO)); hoja.setAtDirClaves(i, dirClave); hoja.setAtDirNodo(i + 1, posB); } } if (hoja.getTipoNodo() == RAIZ || hoja.getTipoNodo() == PAGINA) { clave = claveAux; dirClave = dirAux; }else { clave = nuevo.getAtClave(0); dirClave = nuevo.getAtDirClaves(0); } getArchivo().escribeNodo(hoja); nuevo.setDir(getArchivo().ENDF()); getArchivo().escribeNodo(nuevo); return (nuevo); }
/**Manda un dato hasta la pagina hoja y escribir el bloque de datos en esta, en forma recursiva*/ public bool EmpujaDato(long dirNodo, ref Object clave, ref long dirClave, CBloque b, long posB, ref CNodo nueva, ref bool bandera) { CNodo nodoAux = null; int i, res = -1; bool band = true; int tipoPagina = HOJA; nodoAux = getArchivo().leerNodo(dirNodo);//Se lee la pagina for ( i = 0; i < nodoAux.getNumElemnt(); i++) //Serecorren las direccion de sus descendientes(Direcciones a otros nodos) if ((res = nodoAux.comparaClave(i,clave)) != -1) break; if (res == 0) if (nodoAux.getTipoNodo() == RAIZHOJA || nodoAux.getTipoNodo() == HOJA) return (false); else i++; if(band) { if (nodoAux.getTipoNodo() == RAIZHOJA || nodoAux.getTipoNodo() == HOJA)//Estamos en una hoja { if (nodoAux.getNumElemnt() == 2 * GRADO) { tipoPagina = HOJA; nueva = particiona(nodoAux, b, posB, ref clave, ref dirClave, i); bandera = true; } else { nodoAux.insClaveOrd(clave, b, getArchivo(), i); getArchivo().escribeNodo(nodoAux); } } else { //Llamada recursiva band = EmpujaDato(nodoAux.getAtDirNodo(i), ref clave, ref dirClave, b, posB, ref nueva, ref bandera); if (bandera == true) { if (nodoAux.getNumElemnt() == 2 * GRADO) { tipoPagina = nodoAux.getTipoNodo(); nueva = particiona(nodoAux, b, nueva.getDir(), ref clave, ref dirClave, i); } else//Hay espacio para insertar la clave que sube { bandera = false; nodoAux.insClaveOrd(clave, b, getArchivo(), i); nodoAux.setAtDirClaves(i, dirClave); nodoAux.setAtDirNodo(i + 1, nueva.getDir()); getArchivo().escribeNodo(nodoAux); } } } } return (band); }
/**Metodo principal para la inserción de la clave junto con su bloque de datos*/ public bool AltaArbolBplus(CNodoEntidad e, CBloque b, long posB) { CNodo nuevo = null; Object clave; bool res = true; long dirClave = -1; clave = b.dameClavePrim(); if (e.getApCabDatos() == -1)//Si no hay algun arbol se crea la primera pagina { nuevo = new CNodo(RAIZHOJA, GRADO); nuevo.setDir(getArchivo().ENDF()); nuevo.setTipoClave(b.getTipoCA()); getArchivo().escribeNodo(nuevo); e.setApCabDatos(nuevo.getDir()); getArchivo().escribeEntidad(e, e.getDir()); } else { bool bandera = false; res = EmpujaDato(e.getApCabDatos(), ref clave, ref dirClave, b, posB, ref nuevo, ref bandera); if (bandera == true)//La raiz se partido { CNodo nuevaRaiz; nuevaRaiz = new CNodo(RAIZ, GRADO); nuevaRaiz.setAtClave(0, clave); nuevaRaiz.setAtDirClaves(0, dirClave); nuevaRaiz.setAtDirNodo(0, ent.getApCabDatos()); nuevaRaiz.setAtDirNodo(1, nuevo.getDir()); nuevaRaiz.setDir(getArchivo().ENDF()); nuevaRaiz.setNumElemnt(1); nuevaRaiz.setTipoClave(b.getTipoCA()); getArchivo().escribeNodo(nuevaRaiz); e.setApCabDatos(nuevaRaiz.getDir()); getArchivo().escribeEntidad(e, e.getDir()); } } return (res); }
private CNodo creaNodo(CArchivo aO, CArchivo aN, CNodo nodoAux) { CNodo nuevo; nuevo = new CNodo(nodoAux.getTipoNodo(), nodoAux.getGrado()); nuevo.setNumElemnt(nodoAux.getNumElemnt()); nuevo.setTipoClave(nodoAux.getTipoClave()); for(int i = 0; i< nodoAux.getNumElemnt(); i++) { nuevo.setAtDirClaves(i, aN.ENDF()); nuevo.escribeClave(nodoAux.getAtClave(i), aN.ENDF(), nodoAux.getTipoClave(), aN); } nuevo.setDir(aN.ENDF()); aN.escribeNodo(nuevo); return (nuevo); }