internal void LimpiarNodoEnDisco(FileStream archivo, int tamañoEncabezado, IFabricaTextoTamañoFijo <T> fabrica) { //Se limpia el contenido del nodo Siguiente = Utilidades.ApuntadorVacio; Anterior = Utilidades.ApuntadorVacio; Dato = fabrica.FabricarNulo(); GuardarNodoEnDisco(archivo, tamañoEncabezado); }
internal static Nodo <T> CrearNodoDesdeDisco(FileStream archivo, int tamañoEncabezado, int posicion, IFabricaTextoTamañoFijo <T> fabrica) { if (archivo == null) { throw new ArgumentNullException("archivo"); } if (tamañoEncabezado < 0) { throw new ArgumentOutOfRangeException("tamañoEncabezado"); } if (posicion < 0) { throw new ArgumentOutOfRangeException("posicion"); } if (fabrica == null) { throw new ArgumentNullException("fabrica"); } // Se crea un nodo nulo para poder acceder a las propiedades de tamaño calculadas // sobre la instancia el dato de la instancia del nodo. Nodo <T> nuevoNodo = new Nodo <T>(posicion, fabrica.FabricarNulo()); // Se cea un buffer donde almacenarán los bytes leidos byte[] datosBinario = new byte[nuevoNodo.TamañoEnBytes]; // Variables a ser utilizadas luego de que el archivo sea leido string datosCadena = ""; string[] datosSeparados = null; // Se ubica la posición donde deberá estar el nodo y se lee desde el archivo archivo.Seek(nuevoNodo.CalcularPosicionEnDisco(tamañoEncabezado), SeekOrigin.Begin); archivo.Read(datosBinario, 0, nuevoNodo.TamañoEnBytes); // Se converiten los bytes leidos del archivo a una cadena datosCadena = Utilidades.ConvertirBinarioYTexto(datosBinario); // Se quitan los saltos de linea y se separa en secciones datosCadena = datosCadena.Replace(Utilidades.TextoNuevaLinea, ""); datosSeparados = datosCadena.Split(Utilidades.TextoSeparador); // Se asignan los apuntadores de Anterior y Siguiente nuevoNodo.Anterior = Convert.ToInt32(datosSeparados[1]); nuevoNodo.Siguiente = Convert.ToInt32(datosSeparados[2]); // Se regenera el objeto Dato utilizando la fabrica nuevoNodo.Anterior = Convert.ToInt32(datosSeparados[1]); nuevoNodo.Siguiente = Convert.ToInt32(datosSeparados[2]); // Se retorna el nodo luego de agregar toda la información return(nuevoNodo); }
private void UbicarPosicion(int posicion, ref Nodo <T> nodoAnterior, ref Nodo <T> nodoActual) { nodoAnterior = null; nodoActual = Nodo <T> .CrearNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, _cabeza, _fabrica); for (int i = 0; i < posicion; i++) { nodoAnterior = nodoActual; if (nodoActual.Siguiente == Utilidades.ApuntadorVacio) { nodoActual = new Nodo <T>(-1, _fabrica.FabricarNulo()); } else { nodoActual = Nodo <T> .CrearNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, nodoActual.Siguiente, _fabrica); } } }
//Limpia un nodo para poder inicializarlos private void LimpiarNodo(IFabricaTextoTamañoFijo <T> fabrica) { Hijos = new List <int>(); for (int i = 0; i < Orden; i++) { Hijos.Add(Utilidades.ApuntadorVacio); } Llaves = new List <string>(); for (int i = 0; i < Orden - 1; i++) { Llaves.Add("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); } Datos = new List <T>(); for (int i = 0; i < Orden - 1; i++) { Datos.Add(fabrica.FabricarNulo()); } }
private void LimpiarNodo(IFabricaTextoTamañoFijo <T> fabrica) { Children = new List <int>(); for (int i = 0; i < Orden; i++) { Children.Add(Utilities.ApuntadorVacio); } Keys = new List <int>(); for (int i = 0; i < Orden - 1; i++) { Keys.Add(Utilities.ApuntadorVacio); } Datos = new List <T>(); for (int i = 0; i < Orden - 1; i++) { Datos.Add(fabrica.FabricarNulo()); } }
private void Subir(NodoB <T> nodoActual, string llave, T dato, int hijoDerecho) { // Si el nodo no está lleno, se agrega la información // al nodo y el método termina if (!nodoActual.Lleno) { nodoActual.AgregarDato(llave, dato, hijoDerecho); nodoActual.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); return; } // Creo un nuevo nodo hermano NodoB <T> nuevoHermano = new NodoB <T>(Orden, _ultimaPosicionLibre, nodoActual.Padre, _fabrica); _ultimaPosicionLibre++; // Datos a subir al padre luego de la separación string llavePorSubir = "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"; T datoPorSubir = _fabrica.FabricarNulo(); // Se llama al método que hace la separación nodoActual.SepararNodo(llave, dato, hijoDerecho, nuevoHermano, ref llavePorSubir, ref datoPorSubir); // Actualizar el apuntador en todos los hijos NodoB <T> nodoHijo = null; for (int i = 0; i < nuevoHermano.Hijos.Count; i++) { if (nuevoHermano.Hijos[i] != Utilidades.ApuntadorVacio) { // Se carga el hijo para modificar su apuntador al padre nodoHijo = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, nuevoHermano.Hijos[i], _fabrica); nodoHijo.Padre = nuevoHermano.Posicion; nodoHijo.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); } else { break; } } // Evaluo el caso del Padre if (nodoActual.Padre == Utilidades.ApuntadorVacio) // Es la raiz { // Creo un nuevo nodo Raiz NodoB <T> nuevaRaiz = new NodoB <T>(Orden, _ultimaPosicionLibre, Utilidades.ApuntadorVacio, _fabrica); _ultimaPosicionLibre++; Altura++; // Agrego la información nuevaRaiz.Hijos[0] = nodoActual.Posicion; nuevaRaiz.AgregarDato(llavePorSubir, datoPorSubir, nuevoHermano.Posicion); // Actualizo los apuntadores al padre nodoActual.Padre = nuevaRaiz.Posicion; nuevoHermano.Padre = nuevaRaiz.Posicion; _raiz = nuevaRaiz.Posicion; // Guardo los cambios nuevaRaiz.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); nodoActual.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); nuevoHermano.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); } else // No es la raiz { nodoActual.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); nuevoHermano.GuardarNodoEnDisco(_archivo, _tamañoEncabezadoBinario); // Cargar el nodo Padre NodoB <T> nodoPadre = NodoB <T> .LeerNodoDesdeDisco(_archivo, _tamañoEncabezadoBinario, Orden, nodoActual.Padre, _fabrica); Subir(nodoPadre, llavePorSubir, datoPorSubir, nuevoHermano.Posicion); } }