/// <summary> /// Indica si el par {llave,valor} está contenida en el B-Tree /// </summary> /// <param name="key">Llave a verificar</param> /// <returns></returns> public bool Contains(T key, R value) { MiPar <T, R> result = Search(key, value); if (result == null) { return(false); } return(true); }
/// <summary> /// Elimina del B-Tree el par {llave,valor} a partir de la raíz /// </summary> /// <param name="x">Nodo raíz</param> /// <param name="k">Llave a eliminar</param> /// <param name="v">Valor a eliminar</param> /// <returns></returns> private MiPar <T, R> Delete(BTreeNode <T, R> x, T k, R v) { int index = buscarEnNodo(x, k, v, false); //int index = buscarEnNodoSec(x, k, v); if (x.IsLeaf)//Caso 1 { if (index == -1) { return(null); } MiPar <T, R> result = new MiPar <T, R>(x.Keys[index], x.Satellite[index]); for (int i = index; i < x.CantKeys - 1; i++) { x.Keys[i] = x.Keys[i + 1]; x.Satellite[i] = x.Satellite[i + 1]; } x.CantKeys--; //RAM.Update(x); return(result); } else //x es un nodo interno(casos 2 y 3) { if (index != -1)//x contiene a k(caso 2) { BTreeNode <T, R> y = GetNode(x.Children[index]); //llamar al FileManager y DISK_READ(x.Children[index]) predecessor child; if (y.CantKeys >= t) //y tiene al menos t llaves { //caso 2a BTreeNode <T, R> max = Maximo(y); T aux = max.Keys[max.CantKeys - 1]; R val = max.Satellite[max.CantKeys - 1]; //addded x.Keys[index] = aux; x.Satellite[index] = val; //added //RAM.Update(x);//added return(Delete(y, aux, val)); } else //y tiene t-1 llaves { //caso 2b BTreeNode <T, R> z = GetNode(x.Children[index + 1]);//llamar al FileManager y DISK_READ(x.Children[index + 1]) sucessor child; if (z.CantKeys >= t) { BTreeNode <T, R> min = Minimo(z); T aux = min.Keys[0]; R val = min.Satellite[0]; //added x.Keys[index] = aux; x.Satellite[index] = val; //added //RAM.Update(z);//added return(Delete(z, aux, val)); } else//tanto y como z tienen t-1 llaves {//caso 2c Merge(x, y, z, index);//revisar bien aqui(buscar en la hoja del pseudocodigo) return(Delete(y, k, v)); } } } else//x no contiene a k(caso 3) { int i = 0; while (i < x.CantKeys && Compare(k, x.Keys[i], v, x.Satellite[i]) > 0)//change k.CompareTo(x.Keys[i]) > 0 { i++; } BTreeNode <T, R> c = GetNode(x.Children[i]);//DISK_READ(x.Children[i]); if (c.CantKeys == t - 1) { bool primero = (i == 0); bool ultimo = (i == x.CantKeys); BTreeNode <T, R> y = new BTreeNode <T, R>(); BTreeNode <T, R> z = new BTreeNode <T, R>(); if (!primero) { y = GetNode(x.Children[i - 1]);// DISK_READ(x.Children[i-1]) predecessor brother; } if (!ultimo) { z = GetNode(x.Children[i + 1]); //DISK_READ(x.Children[i+1]) sucessor brother; } if ((!primero && y.CantKeys >= t) || (!ultimo && z.CantKeys >= t)) //caso 3a { if (!primero && y.CantKeys >= t) { //la llave a bajar del padre es la i-1 Array.Copy(c.Keys, 0, c.Keys, 1, c.CantKeys); Array.Copy(c.Satellite, 0, c.Satellite, 1, c.CantKeys);//added Array.Copy(c.Children, 0, c.Children, 1, c.CantKeys + 1); c.Keys[0] = x.Keys[i - 1]; c.Satellite[0] = x.Satellite[i - 1];//added c.Children[0] = y.Children[y.CantKeys]; x.Keys[i - 1] = y.Keys[y.CantKeys - 1]; x.Satellite[i - 1] = y.Satellite[y.CantKeys - 1];//added c.CantKeys++; y.CantKeys--; //RAM.Update(x); //RAM.Update(c); //RAM.Update(y); } else if (!ultimo && z.CantKeys >= t) { //la llave a bajar del padre es la i c.Keys[c.CantKeys] = x.Keys[i]; c.Satellite[c.CantKeys] = x.Satellite[i];//added c.Children[c.CantKeys + 1] = z.Children[0]; x.Keys[i] = z.Keys[0]; x.Satellite[i] = z.Satellite[0]; //added Array.Copy(z.Keys, 1, z.Keys, 0, z.CantKeys - 1); Array.Copy(z.Satellite, 1, z.Satellite, 0, z.CantKeys - 1); //added Array.Copy(z.Children, 1, z.Children, 0, z.CantKeys); c.CantKeys++; z.CantKeys--; //RAM.Update(x); //RAM.Update(c); //RAM.Update(z); } return(Delete(c, k, v)); } else //c y sus dos hermanos tienen t-1 llaves { //caso 3b if (!primero) { Merge(x, y, c, i - 1); return(Delete(y, k, v)); } else /*if (!ultimo)*/ { Merge(x, c, z, i /*i-1*/); return(Delete(c, k, v)); } } // if (!primero && y.CantKeys >= t) // return Delete(y, k, v); // else // return Delete(c, k, v); } else { return(Delete(c, k, v)); } } } }