noter:
Evidentemente al segundo.
Supongo que la duda se debe a que sería un desperdicio de tiempo reubicar un registro que se supone que está eliminado.
Digamos que vamos a seguir con la idea de mover un registro a la vez y que ya tienes cómo desplazar un registro en un puntero válido. Entonces los cambios son los siguientes:
- Ya que habrá que iterar sobre los punteros inválidos también, el límite del ciclo se definirá por la suma de ambas cantidades (almacenar el resultado de la suma porque en cada iteración esta se ejecuta); obviamente estamos hablando del tamaño total de la tabla de índices, expresado en cantidad de elementos.
- Cuando se halle la coincidencia, verificar en qué parte de la tabla está. Si el contador es menor que la cantidad de punteros válidos, entonces proceder de la manera conocida; caso contrario, proceder de igual forma salvo que no se copia el registro entero, solo se modifica el valor del puntero por el final del archivo (en teoría se puede usar size() para esto, pero no estoy seguro si ese valor se actualiza apenas se hace crecer el archivo; debería, pero tengo la corazonada de que no es así).
- Luego actualizar, en la cabecera, los datos de posición (supongo que absoluta) del primer byte del primer registro y la cantidad de espacios libres. El primero es fácil, el segundo no tanto.
La cantidad de espacio recuperado para índices se calcula mediante la siguiente operación:
espaciosLibres += tamanioRegistro / 4;
residuo += tamanioRegistro % 4;
if (residuo >= 4) {
espaciosLibres++;
residuo -= 4; // Realizar esto sólo si es un atributo de la instancia y no una variable local
}
Note esta variable llamada residuo, se usa para determinar cuándo se da el caso de que se recupera espacio para un índice extra. Eso sí, esto nunca va a ocurrir cuando el tamaño del registro es múltiplo de 4.
Esta variable puede ser atributo o local, y su valor inicial se obtiene calculando la brecha entre el último puntero de la tabla y el primer byte del primer registro (¿lo llamas _head.dataStart?). Observa que estamos hablando del residuo de una división; por lo tanto, el valor calculado debe ser mayor o igual a cero, pero menor que 4.
El fragmento de código anterior es ilustrativo y los nombres de variables son ejemplos; tú sabrás cómo se llaman en realidad...
Para reclamar espacio de múltiples registros, es nada más repetir, las veces necesarias, todo lo anterior.
Si el proceso de inserción está programado para tomar siempre el primer puntero inválido, entonces no deberíamos tener problemas con que mandemos a escribir fuera del límite inicial del archivo (position() > size()). ¡ATENCIÓN! Que eso implica que en la operación de eliminación, el puntero ahora inválido debe ser desplazado siempre al final de la tabla.
PD: ¿que pasaría si en el proceso no se encontrara al "dueño" del espacio a reclamar? Lógicamente sería seña de archivo corrupto o alterado deliberadamente, pero... ¿nunca los habías pensado?