Changeset f8287df in tol


Ignore:
Timestamp:
Jun 26, 2009, 11:08:01 AM (17 years ago)
Author:
Víctor de Buen <vdebuen@…>
Branches:
1941-docker-image-to-test, devel, master
Children:
ceaefa5
Parents:
ec15ab4
Message:

New function Ois.SerSetCumCache to accelerate repetitive access to massive data stores of time series.

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1119 be4846ae-f051-483a-831f-b64e7d08527f

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tol/stdlib/data/ois/_ois.tol

    rec15ab4 rf8287df  
    103103Ois.GetAddress);
    104104//////////////////////////////////////////////////////////////////////////////
     105
     106
     107//////////////////////////////////////////////////////////////////////////////
     108  Set Ois.SerSetCumCache(NameBlock serSetGen,
     109                         Date askFrom,
     110                         Date askUntil,
     111                         Real caducityInMinutes)
     112//////////////////////////////////////////////////////////////////////////////
     113{
     114  Text key = serSetGen::getKey(0);
     115  Text _MID = "[Ois.SerSetCumCache "+key+"]:\n";
     116  Text cacheFile = Ois.DefRoot+"Ois.SerSetCumCache/"+key+".oza";
     117
     118  WriteLn("TRACE "+_MID+" Caducidad de la caché en minutos: "<<caducityInMinutes);
     119  Real If(caducityInMinutes<=0,
     120  {
     121    WriteLn("TRACE "+_MID+"Se borra la caché porque la caducidad es nula "
     122            "o negativa");
     123    OSFilRemove(cacheFile)
     124  });
     125  Real cacheExist = FileExist(cacheFile);
     126  Date cacheDate = If(cacheExist, FileTime(cacheFile), TheBegin);
     127  Real cacheAge = If(cacheExist, DateDif(S(0), cacheDate, Now), 1/0);
     128  WriteLn("TRACE "+_MID+" Fecha de la caché: "<<cacheDate);
     129  WriteLn("TRACE "+_MID+" Antigüedad de la caché en minutos: "<<cacheAge);
     130  Real cacheValid = If(cacheAge>=caducityInMinutes, False, True);
     131  Set cacheData = If(cacheValid, Include(cacheFile), Copy(Empty));
     132  Date cacheFrom = SetMinDate([[TheEnd]] <<EvalSet(cacheData, First));
     133  Date cacheUntil = SetMaxDate([[TheBegin]]<<EvalSet(cacheData, Last ));
     134  NameBlock avail = serSetGen::getAvail(0);
     135  Date askAvaiFrom = Max(askFrom, avail::first);
     136  Date askAvailUntil = Min(askUntil, avail::last);
     137
     138  WriteLn("TRACE "+_MID+" Intervalo solicitado: ["<<askFrom+","<<askUntil+"]");
     139  WriteLn("TRACE "+_MID+" Intervalo disponible en origen: ["<<avail::first+","<<avail::last+"]");
     140  WriteLn("TRACE "+_MID+" Intervalo intersección: ["<<askAvaiFrom+","<<askAvailUntil+"]");
     141  WriteLn("TRACE "+_MID+" Intervalo almacenado en la caché: ["<<cacheFrom+","<<cacheUntil+"]");
     142 
     143  //Método local usado cuando no es posible usar la cache actual
     144  Set getAllData(Real unused)
     145  {
     146    Set ask = serGen::getData(askAvaiFrom, askAvailUntil);
     147    Real OSFilRemove(cacheFile);
     148    Real Ois.Store(ask, cacheFile);
     149    ask
     150  };
     151
     152  Set series = Case(
     153  (askAvaiFrom > askAvailUntil),
     154  {
     155    WriteLn(_MID+"No hay datos disponibles entre las fechas solicitadas ["<<
     156            askFrom+","<<askUntil+"]","W");
     157    Copy(Empty)
     158  },
     159  And(askAvaiFrom>=cacheFrom, askAvailUntil<=cacheUntil),
     160  {
     161    WriteLn("TRACE "+_MID+"Todos los valores solicitados estaban ya en la cache");
     162    EvalSet(cacheData, Serie(Serie ser)
     163    {
     164      Serie sub = SubSer(ser, askAvaiFrom, askAvailUntil);
     165      Eval(Name(ser)+"=sub")
     166    })
     167  },
     168  And(askAvaiFrom>=cacheFrom, askAvailUntil>cacheUntil),
     169  {
     170    WriteLn("TRACE "+_MID+"Intentando actualización acumulativa de la cache "
     171    "en el intervalo de nuevos datos ["<<cacheUntil+","<<askAvailUntil+"]");
     172    Set newData = serGen::getData(cacheUntil,askAvailUntil);
     173    If(Card(newData)>Card(cacheData),
     174    {
     175      WriteLn(_MID+"La actualización acumulativa de la cache no se puede "
     176        "ejecutar porque los nuevos datos contienen mayor número de series ("<<
     177        Card(newData)+") que los de la cache ("<<Card(cacheData)+")","W");
     178      getAllData(0)
     179    },
     180    {
     181      Real numErr0 = Copy(NError);
     182      Set cache = For(1,Card(cacheData), Serie(Real k)
     183      {
     184        Text name = Name(cacheData[k]);
     185        If(!ObjectExist("Serie","newData[\""+name+"\"]"),
     186        {
     187          cacheData[k]
     188        },
     189        {
     190          Serie sub = cacheData[k]<<newData[name];
     191          Eval(name+"=sub")
     192        })
     193      });
     194      Real numErr1 = Copy(NError);
     195      If(numErr1>numErr0,
     196      {
     197        WriteLn(_MID+"La actualización acumulativa de la cache no se puede "
     198          "ejecutar porque los nuevos datos no contienen algunas series de "
     199          "las de la cache: "+notFound,"W");
     200        getAllData(0)
     201      },
     202      {
     203        WriteLn("TRACE "+_MID+"La actualización parcial de la cache se "
     204          "ejecutó con éxito.");
     205        Real OSFilRemove(cacheFile);
     206        Real Ois.Store(cache, cacheFile);
     207        Set ask = For(1,Card(cache), Serie(Real k)
     208        {
     209          Serie sub = SubSer(cache[k], askAvaiFrom, askAvailUntil);
     210          Eval(Name(cache[k])+"=sub")
     211        });
     212        ask
     213      })
     214    })
     215  },
     216  1==1,
     217  {
     218    WriteLn("TRACE "+_MID+" La cache ha tenido que ser reconstruida por completo");
     219    getAllData(0)
     220  })   
     221
     222};
     223//////////////////////////////////////////////////////////////////////////////
     224PutDescription("Añade una caché acumulativa a un mecanismo genérico de "
     225"obtención de series temporales que van creciendo con el tiempo, que viene "
     226"definido por un NameBlock serSetGen con una serie de métodos obligatorios.\n"
     227"En último término las series temporales provendrán de una base de datos, un "
     228"data warehouse o algún otro mecanismo de almacenamiento masivo.\n"
     229"La utilidad de este algoritmo es minimizar el número y el volumen de las "
     230"consultas realizadas sobre los orígenes de los datos.\n"
     231"El método "
     232"  NameBlock serSetGen::getAvail(Real unused) \n"
     233"retorna el intervalo temporal  para el que existen datos disponibles. "
     234"  NameBlock avail = [[ Date first, Date Last ]]\n"
     235"La primera vez que se le llama almacenan los datos devueltos por el "
     236"método \n "
     237"  Set serSetGen::getData(avail::first, avail::last) \n"
     238"en un OIS ubicado por un texto clave propiedad característica del método \n"
     239"  Text getKey(Real unused) \n"
     240"Luego se devolverán esas series pero recortadas al intervalo de "
     241"intersección entre el disponible y el solicitado [askFrom, askUntil].\n"
     242"Si se desea obtener todos los datos disponibles basta con pasar\n"
     243"Date askFrom= TheBegin, Date askUntil=TheEnd\n"
     244"El método devolverá un conjunto, preferiblemente indexado, de series con "
     245"nombres localmente únicos, para poder reconocer los distintos elementos, "
     246"ya que según el intervalo solicitado es posible que se devuelvan más o "
     247"menos series.\n"
     248"Las veces subsiguientes la función rescatará los datos almacenados en la "
     249"cache y solicitará únicamente los datos más recientes que hayan aparecido "
     250"desde que se efectuó la cache, si es que los hay, en cuyo caso serán "
     251"concatenados a los datos antiguos para las series que hayan crecido, y se "
     252"reactualizará el fichero OIS de la cache, razón por la cual esta técnica "
     253"recibe el nombre de caché acumulativa. Si no hubiera datos nuevos "
     254"simplemente se devolverán los datos de la cache almacenada en el intervalo "
     255"colicitado.\n"
     256"Si se detecta cualquier discrepancia o incompatibilidad entre la cache y "
     257"los nuevos datos o entre el intervalo de disponibilidad actual y el "
     258"almacenado entonces se destruirá la caché y se empezará desde cero.\n"
     259"Si el archivo de la caché tiene una vida mayor que la caducidad "
     260"especificada por caducityInMinutes entonces se borrará la caché y se "
     261"empezará de nuevo. Con este parámetro puesto a 0 se obligaría a limpiar la "
     262"cache cuando por cualqueir circunstancia se sepa o sospeche que puede haber "
     263"discrepancias entre los datos de la cache y los originales, a parte de los "
     264"datos nuevos, bien por cualquier fallo durante el proceso de la cache, bien "
     265"porque se hayan actualizado las propias fuentes de los datos históricos.\n"
     266"Por el contrario, poniendo caducityInMinutes=1/0 es posible trabajar con "
     267"una copia local congelada de los datos, bien para protegerse de algún "
     268"problema detectado en la alimentación de los datos originales, bien porque "
     269"eventualmnete no se dispone de conexión a los recursos de almacenamiento "
     270"de los mismos.",
     271Ois.SerSetCumCache);
     272//////////////////////////////////////////////////////////////////////////////
     273
Note: See TracChangeset for help on using the changeset viewer.