Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
                }
            }
        }
Esempio n. 4
0
        //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());
            }
        }
Esempio n. 5
0
        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());
            }
        }
Esempio n. 6
0
        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);
            }
        }