
                                MEGA-PRO2-LOAD

Consideremos una organizacin que permite la descarga de pelculas a sus
clientes desde su red de servidores. Modelaremos esta red (es decir, las
conexiones entre servidores) mediante una estructura arbrea de exactamente N
nodos, identificados con los valores 1..N, donde N es un entero mayor que cero.
Existe un nodo especial, el servidor central, que recibir todas las
peticiones, y que estar conectado directamente con un mximo de dos nodos.
Estos, a la vez, podrn estar conectados directamente con otros dos nodos como
mximo, y as sucesivamente.

Ejemplo de red (estructura de conexiones): los nmeros indican los
identificadores de los servidores (o nodos) y las lneas indican la conexin
entre ellos. El nodo 10 es el servidor central (inicio de todos los caminos) y
los nodos 1, 2, 4, 6 y 7 son nodos final de camino.
                         
                      
                           10
                       /        \
                     9            5
                   /   \             \              
                  3     4             8
                 /  \                / \
                1    2              6   7


Las pelculas que la organizacin permite descargar son conocidas a priori,
siendo su nmero una constante M (un entero mayor que cero). Cada pelcula
tendr un identificador entero entre 1 y M, y de cada una de ellas conoceremos
su tamao en Megabytes (un entero mayor que cero). No todos los servidores
dispondrn necesariamente de todas las pelculas, sino que cada servidor
contendr un determinado subconjunto de las mismas, que podr ser actualizado
en cualquier momento.

Cada servidor se caracteriza por un determinado ancho de banda, medido en
Mb/ut, que representa su capacidad de descarga (Megabytes por unidad de
tiempo).  Discretizaremos el tiempo en unidades enteras (podran representar
segundos, por ejemplo) y no fraccionables (no podr hablarse de 27 unidades y
media, de 34,68 unidades, etc.) Usaremos las mismas unidades tanto para definir
instantes de tiempo como duraciones de descargas.  Por ejemplo, si una descarga
empieza en el instante 70 y tiene una duracin de 14 unidades, entonces acabar
en el instante 84.

En cada instante de tiempo, un servidor puede estar desocupado o totalmente
dedicado a la descarga de una sola pelcula (y de una sola peticin)
directamente al cliente que la ha pedido.


Peticiones de descargas y asignacin de servidores a las mismas
===============================================================

Cuando un cliente solicita la descarga de una determinada pelcula, se genera
una nueva peticin en el sistema, que tendr identificador propio (un natural
correlativo) y que deber atenderse comenzando en un cierto tiempo inicial de
descarga t_i dado. El servidor central recibe la peticin y selecciona,
siguiendo una determinada poltica, los servidores que atendern la misma.  Los
servidores seleccionados pasarn entonces a enviar (en paralelo) partes de la
pelcula al cliente que la ha solicitado, usando todo su ancho de banda.  La
distribucin de las partes de cada pelcula que enva cada servidor no es
relevante para esta prctica.

Una primera restriccin obvia es que los servidores seleccionados deben
disponer de la pelcula solicitada. Una segunda es que deben estar libres en el
tiempo t_i, es decir, ha de haber acabado la ltima descarga a la que fueron
asignados (si la hubiera). Una tercera es que deben pertenecer todos al mismo
camino desde el servidor central en la estructura de red de conexin.

Sea S={s_1,...,s_j,...,s_n} un subconjunto de n servidores, n>=1, tales que
todos disponen de la pelcula solicitada en una peticin, estn libres en el
tiempo t_i y pertenecen todos a un mismo camino en la red de conexiones.
Supongamos que s_1 es el ms cercano al servidor central (podra ser l mismo)
y s_n es el ms lejano o profundo. Sean a_1,...,a_j,...,a_n sus respectivos
anchos de banda, sea A la suma de dichos anchos de banda y sea F el tamao de
la pelcula. Entonces, cada servidor se encarga de ofrecer una parte
consecutiva de la pelcula de tamao proporcional a su capacidad de descarga.
Ms concretamente, el tamao de la parte de la pelcula de la que se encarga el
servidor s_j ser F*(a_j / A). Notad que al distribuir de esta manera la
descarga de la pelcula, todos los servidores implicados podrn iniciar y
acabar la descarga al mismo tiempo y la duracin D de la descarga en unidades
de tiempo ser el entero ms pequeo mayor o igual que F / A.  Entonces, t_f =
t_i + D ser la unidad de tiempo final en la que los servidores implicados
volvern a estar libres y la peticin habr sido servida completamente.

Para elegir entre los diferentes subconjuntos de servidores posibles, se
aplicarn dos criterios de decisin. El primer criterio, el ms prioritario,
establece que, si existen subconjuntos de servidores en las condiciones
anteriores que permiten la descarga conjunta de la pelcula en una nica unidad
de tiempo, se elija aquel cuyo nodo ms profundo est ms cerca del servidor
central, con la obligacin de usar todos los servidores libres intermedios que
contengan la pelcula. En caso de existir varios subconjuntos de profundidad
mnima, se elige aquel cuyo nodo ms profundo est ms a la izquierda en la
estructura arbrea de servidores.

Si tras aplicar el primer criterio no se obtiene ninguna solucin, entonces se
aplica el segundo, que establece que, entre los diferentes caminos, se elija
aquel que suma ms ancho de banda entre los servidores del camino que disponen
de la pelcula y estn libres (en caso de empate, se elige aquel subconjunto
cuyo nodo a usar ms profundo est ms cerca del servidor central y si persiste
el empate, aquel cuyo nodo a usar ms profundo est ms a la izquierda en la
estructura arbrea de servidores).

Si tras aplicar el segundo criterio sigue sin haber ninguna solucin, significa
que ningn servidor est disponible para descargar la pelcula solicitada, ya
sea porque en el momento de la peticin todos los nodos que la tienen estn
ocupados o porque simplemente ninguno la tiene en ese momento. En ese caso, la
peticin se considera no aceptada y no tendr ningn efecto en el sistema
(excepto que habr consumido un identificador de peticin).
 

Consultas de estado de peticiones y servidores
==============================================

El sistema ir recibiendo y atendiendo peticiones de descargas de pelculas en
orden cronolgico. Supondremos que el tiempo inicial de descarga para una nueva
peticin siempre ser mayor que el tiempo inicial especificado en la peticin
precedente. Este orden en que se empiezan a procesar las peticiones no ser en
general el mismo en el que acaban, ya que este ltimo depende tambin de las
duraciones de las descargas.

El administrador del sistema podr consultar cul es el estado de las
peticiones o de los servidores (mediante sendas operaciones) en un tiempo dado
t, que ser siempre posterior al de la ltima peticin y al de la ltima
consulta realizada (el tiempo de una nueva peticin tambin ha de ser posterior
al de la ltima consulta realizada).  Como consecuencia, en un mismo instante t
solo se puede realizar una consulta o peticin.

En el caso de las peticiones, interesa conocer las que todava no se han
acabado de servir en t, y de cada una de ellas, su identificador, la pelcula
solicitada y los tiempos inicial y final de descarga. En el caso de los
servidores, interesa conocer los que estn ocupados en t en alguna descarga no
finalizada, y de cada uno de ellos, su identificador, el de la peticin que
est sirviendo y el tiempo que le resta para quedar libre.

Es importante darse cuenta que, entre el tiempo en que se realiz la peticin o
consulta precedente y el de la peticin o consulta actual, una o ms peticiones
pueden haber acabado de descargarse liberando algunos servidores.  En
consecuencia, estas operaciones pueden aprovecharse para efectuar tambin las
actualizaciones necesarias en el sistema para poder obtener el resultado
correcto de manera eficiente. Consideraremos que, si una operacin de peticin
o consulta se realiza en un instante t, las peticiones cuyo tiempo final t_f
sea igual a t son peticiones ya servidas completamente (obviamente, si su t_f
es menor que t, tambin) y los servidores implicados en las mismas estarn
libres en t a efectos de dicha operacin (la seleccin de servidores si se
trata de una peticin y los listados correspondientes si se trata de una
consulta).


Actualizacin de pelculas en servidores y estadsticas de pelculas
====================================================================

En cualquier momento ser posible actualizar las pelculas que contiene un
servidor, indicando cules se dan de alta y cules se dan de baja en dicho
servidor. Esto no afectar a las descargas ya iniciadas, incluso si el
servidor interviene en alguna de ellas, sino nicamente a las futuras
peticiones. Como se ha mencionado al principio, supondremos que la coleccin
global de M pelculas en el sistema no se modifica, por lo que las altas no
sern pelculas nuevas, sino pelculas ya existentes en la coleccin. De forma
similar, aunque despus de una baja resulte que ningun servidor contiene una
cierta pelcula, dicha pelcula no se eliminar de la coleccin.

Por otro lado, el sistema podr ofrecer estadsticas sobre las descargas de
pelculas. Para simplificar, consideraremos solamente una operacin de consulta
de este tipo, en la que, dado un intervalo de tiempos [t1..t2], se desea saber
cul es la pelcula ms solicitada en dicho intervalo, junto con su nmero de
peticiones en el mismo, teniendo en cuenta para ello slo aquellas peticiones
aceptadas cuyo tiempo inicial sea >= t1 y <= t2.


SE PIDE:
========

Disear un programa modular razonablemente eficiente que permita gestionar las
peticiones de descargas, consultar el estado de las mismas y de los servidores,
actualizar las pelculas de un servidor y determinar la pelcula ms solicitada
en un intervalo de tiempo. En primer lugar, debe leer el nmero M de pelculas
y el tamao en Mb (un entero mayor que cero) de cada pelcula.  Luego debe leer
el nmero de servidores N, su estructura de conexin y las propiedades de cada
servidor, que sern su ancho de banda en Mb/ut (un entero mayor que cero) y las
pelculas de que dispone inicialmente.  Seguidamente deber inicializar una
estructura de datos vaca para las peticiones de los clientes. Despus tendr
que ir procesando las diversas tareas que se le pidan.  Estas podrn ser las
siguientes:

1) Dado un identificador de pelcula y un tiempo de inicio de descarga, generar
una nueva peticin. Se le tendr que asignar un nuevo identificador de
peticin, determinar si la peticin puede aceptarse, y en su caso, elegir los
servidores que se usarn para la descarga y calcular el tiempo final en que
acabar la descarga (es decir, en que los servidores usados quedarn libres).

Si la peticin no se puede satisfacer, se deber escribir el identificador de
peticin y un cero. En caso contrario, se escribir el identificador de
peticin, la duracin de la descarga y los identificadores de los servidores a
usar en la misma, en el orden creciente de identificador. Para ello, habr que
tener en cuenta los recursos liberados por las peticiones acabadas antes del
tiempo de inicio.  Tambin se debern actualizar los datos para las
estadsticas de descargas de la pelcula solicitada (slo en el caso de poder
atender la peticin).  Aplicaremos la poltica de que las peticiones se irn
realizando en orden cronolgico, es decir, cada nueva peticin tendr un tiempo
inicial posterior al de las peticiones (y consultas) que la han precedido
(notad que eso no tiene por qu ser as en el caso de los tiempos finales).

2) Dado un tiempo t actual, posterior al inicial de la ltima peticin
solicitada y al de la ltima consulta realizada, escribir las peticiones que
todava no se han acabado de servir en t, ordenadas crecientemente por tiempo
final (y en caso de empate, por identificador de peticin). Para cada una de
ellas, se deber escribir su identificador, la pelcula solicitada y los
tiempos inicial y final de descarga.

3) Dado un tiempo t actual, posterior al inicial de la ltima peticin
solicitada y al de la ltima consulta realizada, escribir los servidores que
estn ocupados en t en alguna descarga no finalizada, ordenados crecientemente
por identificador de servidor. Para cada uno de ellos, se deber escribir su
identificador, el de la peticin que est sirviendo y el tiempo que le resta
para quedar libre.

4) Dado un identificador de servidor k entre 1 y N, actualizar las pelculas
que contiene, leyendo las altas y/o bajas del canal de entrada. En las altas y
bajas, no se crean nuevas pelculas ni se eliminan pelculas de la coleccin
de la organizacin. Asumiremos que esta operacin no afecta a las descargas ya
iniciadas; la actualizacin slo se tendr en cuenta para las siguientes
peticiones.

5) Dados dos tiempos t1 y t2, tales que t2 >= t1, escribir el identificador de
la pelcula ms solicitada de entre aquellas solicitudes que hayan sido
aceptadas y su tiempo inicial est en el intervalo de tiempos entre t1 y t2
(ambos inclusive); tambin se ha de escribir su nmero de solicitudes. En caso
de empate se ha de obtener la que tenga el menor identificador. Si no hay
ninguna pelcula en ese intervalo y en las condiciones mencionadas, se
escribirn dos ceros.

La forma de comunicarnos con el programa para que realice dichas tareas ser
parecida a la del caso de estudio "Cubeta" que aparece en la sesin 8 de
laboratorio.  Podis disear un esquema provisional que ya refinaris cuando
conozcis el juego de pruebas pblico.

En das sucesivos se completarn los detalles que se hayan podido pasar por
alto en este enunciado y se publicarn las aclaraciones oportunas.

La sintaxis *exacta* de los datos y resultados, acompaada del juego de pruebas
pblico, se conocer tres semanas antes del da de entrega de la prctica.
Hasta entonces no podris implementar de forma definitiva las operaciones de
lectura y escritura necesarias para los tipos que utilicis, aunque s podris
especificarlas.