Commit 65151f68 authored by Thomas Jahns's avatar Thomas Jahns 🤸
Browse files

Enable resource lists to enforce IDs.

* And make use of this capability in Z-axis.
parent b2b2e660
......@@ -232,6 +232,19 @@ void listSizeExtend()
/**************************************************************/
static void
reshPut_(int nsp, int entry, void *p, const resOps *ops)
{
listElem_t *newListElem = resHList[nsp].resources + entry;
int next = newListElem->res.free.next;
if (next != -1)
resHList[nsp].resources[next].res.free.prev = -1;
resHList[nsp].freeHead = next;
newListElem->res.v.val = p;
newListElem->res.v.ops = ops;
newListElem->status = RESH_ASSIGNED;
}
int reshPut ( void *p, const resOps *ops )
{
xassert ( p && ops );
......@@ -245,14 +258,7 @@ int reshPut ( void *p, const resOps *ops )
if ( resHList[nsp].freeHead == -1) listSizeExtend();
int entry = resHList[nsp].freeHead;
cdiResH resH = namespaceIdxEncode2(nsp, entry);
listElem_t *newListElem = resHList[nsp].resources + entry;
int next = newListElem->res.free.next;
if (next != -1)
resHList[nsp].resources[next].res.free.prev = -1;
resHList[nsp].freeHead = next;
newListElem->res.v.val = p;
newListElem->res.v.ops = ops;
newListElem->status = RESH_ASSIGNED;
reshPut_(nsp, entry, p, ops);
LIST_UNLOCK();
......@@ -261,6 +267,18 @@ int reshPut ( void *p, const resOps *ops )
/**************************************************************/
static void
reshRemove_(int nsp, int idx)
{
int curFree = resHList[nsp].freeHead;
listElem_t *r = resHList[nsp].resources;
r[idx].res.free.next = curFree;
if (curFree != -1)
r[curFree].res.free.prev = idx;
r[idx].status = RESH_UNUSED;
resHList[nsp].freeHead = idx;
}
void reshRemove ( cdiResH resH, const resOps * ops )
{
int nsp;
......@@ -274,24 +292,40 @@ void reshRemove ( cdiResH resH, const resOps * ops )
nspT = namespaceResHDecode ( resH );
xassert ( nspT.nsp == nsp &&
nspT.idx >= 0 &&
nspT.idx < resHList[nsp].size &&
resHList[nsp].resources[nspT.idx].res.v.ops &&
resHList[nsp].resources[nspT.idx].res.v.ops == ops );
xassert ( nspT.nsp == nsp
&& nspT.idx >= 0
&& nspT.idx < resHList[nsp].size
&& resHList[nsp].resources[nspT.idx].status != RESH_UNUSED
&& resHList[nsp].resources[nspT.idx].res.v.ops
&& resHList[nsp].resources[nspT.idx].res.v.ops == ops );
int curFree = resHList[nsp].freeHead;
resHList[nsp].resources[nspT.idx].res.free.next = curFree;
if (curFree != -1)
resHList[nsp].resources[curFree].res.free.prev = nspT.idx;
resHList[nsp].resources[nspT.idx].status = RESH_UNUSED;
resHList[nsp].freeHead = nspT.idx;
reshRemove_(nsp, nspT.idx);
LIST_UNLOCK();
}
/**************************************************************/
void reshReplace(cdiResH resH, void *p, const resOps *ops)
{
xassert(p && ops);
LIST_INIT(1);
LIST_LOCK();
int nsp = namespaceGetActive();
namespaceTuple_t nspT = namespaceResHDecode(resH);
while (resHList[nsp].size <= nspT.idx)
listSizeExtend();
listElem_t *q = resHList[nsp].resources + nspT.idx;
if (q->status != RESH_UNUSED)
{
q->res.v.ops->valDestroy(q->res.v.val);
reshRemove_(nsp, nspT.idx);
}
reshPut_(nsp, nspT.idx, p, ops);
LIST_UNLOCK();
}
static listElem_t *
reshGetElem(const char *caller, cdiResH resH, const resOps *ops)
{
......
......@@ -43,6 +43,7 @@ enum {
void reshListCreate(int namespaceID);
void reshListDestruct(int namespaceID);
int reshPut ( void *, const resOps * );
void reshReplace(cdiResH resH, void *p, const resOps *ops);
void reshRemove ( cdiResH, const resOps * );
int reshCountType ( const resOps * );
......
......@@ -12,11 +12,9 @@
#include "serialize.h"
#include "resource_unpack.h"
#include "taxis.h"
#include "zaxis.h"
extern void gridUnpack ( char *, int, int *, int, void *context);
extern void zaxisUnpack ( char *, int, int *, int, void *context);
extern int streamNint;
/*****************************************************************************/
......@@ -50,7 +48,7 @@ void reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
break;
case ZAXIS:
zaxisUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
nspTarget, context);
nspTarget, context, 1);
break;
case TAXIS:
taxisUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
......
......@@ -131,7 +131,7 @@ void zaxisDefaultValue ( zaxis_t *zaxisptr )
static
zaxis_t *zaxisNewEntry(void)
zaxis_t *zaxisNewEntry(int id)
{
zaxis_t *zaxisptr;
......@@ -139,7 +139,13 @@ zaxis_t *zaxisNewEntry(void)
zaxisDefaultValue ( zaxisptr );
zaxisptr->self = reshPut (( void * ) zaxisptr, &zaxisOps );
if (id == CDI_UNDEFID)
zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
else
{
zaxisptr->self = id;
reshReplace(id, zaxisptr, &zaxisOps);
}
return (zaxisptr);
}
......@@ -182,6 +188,36 @@ int zaxisSize(void)
return reshCountType ( &zaxisOps );
}
static int
zaxisCreate_(int zaxistype, int size, int id)
{
zaxis_t *zaxisptr = zaxisNewEntry(id);
zaxisptr->type = zaxistype;
zaxisptr->size = size;
if ( zaxistype >= CDI_NumZaxistype || zaxistype < 0 )
Error("Internal problem! zaxistype > CDI_MaxZaxistype");
int zaxisID = zaxisptr->self;
zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
if ( *ZaxistypeEntry[zaxistype].stdname )
strcpy(zaxisptr->stdname, ZaxistypeEntry[zaxistype].stdname);
zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
double *vals = (double *)xmalloc(size*sizeof(double));
for ( int ilev = 0; ilev < size; ilev++ )
vals[ilev] = 0.0;
zaxisptr->vals = vals;
return zaxisID;
}
/*
@Function zaxisCreate
......@@ -225,47 +261,15 @@ zaxisDefLevels(zaxisID, levs);
*/
int zaxisCreate(int zaxistype, int size)
{
int ilev;
int zaxisID;
double *vals;
zaxis_t *zaxisptr;
if ( CDI_Debug ) Message("zaxistype=%s levels=%d", zaxisNamePtr(zaxistype), size);
if ( size < 0 ) Error("Negativ number of levels (%d) not allowed!", size);
zaxisInit();
zaxisptr = zaxisNewEntry();
zaxisID = zaxisptr->self;
zaxisptr->type = zaxistype;
zaxisptr->size = size;
if ( zaxistype >= CDI_NumZaxistype || zaxistype < 0)
Error("Internal problem! zaxistype not in [0,CDI_NumZaxistype)");
zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
if ( *ZaxistypeEntry[zaxistype].stdname )
strcpy(zaxisptr->stdname, ZaxistypeEntry[zaxistype].stdname);
zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
vals = (double *) malloc(size*sizeof(double));
for ( ilev = 0; ilev < size; ilev++ ) vals[ilev] = 0.0;
zaxisptr->vals = vals;
if ( CDI_Debug )
Message("zaxistype: %d size: %d ", zaxistype, size);
return (zaxisID);
zaxisInit ();
return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
}
void zaxisDestroyKernel( zaxis_t * zaxisptr )
static void zaxisDestroyKernel( zaxis_t * zaxisptr )
{
int id;
......@@ -1690,7 +1694,8 @@ zaxisGetPackSize(void * voidP, void *context)
void
zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
int * unpackBufferPos, int nspTarget, void *context)
int * unpackBufferPos, int nspTarget, void *context,
int force_id)
{
zaxis_t * zaxisP;
int intBuffer[zaxisNint], memberMask;
......@@ -1704,12 +1709,11 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
zaxisInit ();
zaxisP = zaxisNewEntry();
if ( ! zaxisP ) Error("No memory");
zaxisInit();
xassert(namespaceAdaptKey(intBuffer[0], nspTarget) == zaxisP->self);
zaxisP = zaxisNewEntry(force_id?
namespaceAdaptKey(intBuffer[0], nspTarget)
:CDI_UNDEFID);
zaxisP->prec = intBuffer[1];
zaxisP->type = intBuffer[2];
......
......@@ -3,4 +3,9 @@
int zaxisSize(void);
void
zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
int * unpackBufferPos, int nspTarget, void *context,
int force_id);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment