namespace.c 6.82 KB
Newer Older
1
#include <limits.h>
2
#include <stdlib.h>
3
#include <stdio.h>
4
#include "cdi.h"
5
#include "namespace.h"
Thomas Jahns's avatar
Thomas Jahns committed
6
#include "resource_handle.h"
7
#include "pio_util.h"
8
#include "serialize.h"
Thomas Jahns's avatar
Thomas Jahns committed
9
#include "error.h"
10
#include "cdf_int.h"
11
#include "file.h"
12
#include "cdi_int.h"
Thomas Jahns's avatar
Thomas Jahns committed
13
#include "stream_cdf.h"
14

15
static int nNamespaces = 1;
16
static int activeNamespace = 0;
17

18
#ifdef HAVE_LIBNETCDF
Thomas Jahns's avatar
Thomas Jahns committed
19
#define CDI_NETCDF_SWITCHES nc__create,cdf_def_var_serial,cdfDefTimestep,
20
21
22
23
#else
#define CDI_NETCDF_SWITCHES
#endif

24
25
26
27
28
29
30
31
32
33
34
35
36
#define defaultSwitches {                       \
    cdiAbortC_serial,                           \
      serializeGetSizeInCore,                   \
      serializePackInCore,                      \
      serializeUnpackInCore,                    \
      fileOpen_serial,                          \
      fileClose_serial,                         \
      cdiStreamOpenDefaultDelegate,             \
      cdiStreamDefVlist_,                       \
      cdiStreamWriteVar_,                       \
      cdiStreamwriteVarChunk_,                  \
      cdiStreamCloseDefaultDelegate,            \
      CDI_NETCDF_SWITCHES                       \
37
38
      }

39
40
41
42
struct namespace
{
  int hasLocalFiles;
  statusCode resStage;
43
44
45
46
47
48
  void *switches[NUM_NAMESPACE_SWITCH];
} initialNamespace = {
  .hasLocalFiles = 1,
  .resStage = STAGE_DEFINITION,
  .switches = defaultSwitches
};
49
50

struct namespace *namespaces = &initialNamespace;
51

Thomas Jahns's avatar
Thomas Jahns committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
static int namespacesSize = 1;

#if  defined  (HAVE_LIBPTHREAD)
#  include <pthread.h>

static pthread_mutex_t namespaceMutex = PTHREAD_MUTEX_INITIALIZER;

#  define NAMESPACE_LOCK()         pthread_mutex_lock(&namespaceMutex)
#  define NAMESPACE_UNLOCK()       pthread_mutex_unlock(&namespaceMutex)

#else

#  define NAMESPACE_LOCK()
#  define NAMESPACE_UNLOCK()

#endif


70
71
72
enum {
  intbits = sizeof(int) * CHAR_BIT,
  nspbits = 4,
73
  idxbits = intbits - nspbits,
Deike Kleberg's avatar
Deike Kleberg committed
74
75
  nspmask = (( 1 << nspbits ) - 1) << idxbits,
  idxmask = ( 1 << idxbits ) - 1,
76
77
78
79
};

enum {
  NUM_NAMESPACES = 1 << nspbits,
80
  NUM_IDX = 1 << idxbits,
81
};
82

83

Thomas Jahns's avatar
Thomas Jahns committed
84
#if 0
85
86
void namespaceShowbits ( int n, char *name )
{
87
88
89
  int i;
  unsigned mask;
  char bitvalues[intbits + 1];
90

91
  mask = 1;
92
  for ( i = 0; i < intbits; i++ )
93
    {
94
95
      bitvalues[i] = ((unsigned)n & mask) ? '1':'0';
      mask <<= 1;
96
    }
97
98
  bitvalues[intbits] = '\0';
  fprintf (stdout, "%s: %s\n", name, bitvalues );
99
}
Thomas Jahns's avatar
Thomas Jahns committed
100
#endif
101
102
103
104


int namespaceIdxEncode ( namespaceTuple_t tin )
{
Deike Kleberg's avatar
Deike Kleberg committed
105
  xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
106
  return ( tin.nsp << idxbits ) + tin.idx;
107
}
108

109
int namespaceIdxEncode2 ( int nsp, int idx )
110
{
Deike Kleberg's avatar
Deike Kleberg committed
111
  xassert(nsp < NUM_NAMESPACES && idx < NUM_IDX);
112
113
114
  return ( nsp << idxbits ) + idx;
}

115

Deike Kleberg's avatar
Deike Kleberg committed
116
namespaceTuple_t namespaceResHDecode ( int resH )
117
118
119
{
  namespaceTuple_t tin;

Deike Kleberg's avatar
Deike Kleberg committed
120
121
  tin.idx = resH & idxmask;
  tin.nsp = (int)(((unsigned)( resH & nspmask )) >> idxbits);
122
123
124
125

  return tin;
}

Thomas Jahns's avatar
Thomas Jahns committed
126
127
int
namespaceNew(int hasLocalFiles)
128
{
Thomas Jahns's avatar
Thomas Jahns committed
129
130
131
  int newNamespaceID = -1;
  NAMESPACE_LOCK();
  if (namespacesSize > nNamespaces)
132
    {
Thomas Jahns's avatar
Thomas Jahns committed
133
134
135
136
137
138
139
      /* namespace is already available and only needs reinitialization */
      for (int i = 0; i < namespacesSize; ++i)
        if (namespaces[i].resStage == STAGE_UNUSED)
          {
            newNamespaceID = i;
            break;
          }
140
    }
Thomas Jahns's avatar
Thomas Jahns committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  else if (namespacesSize == 1)
    {
      /* make room for additional namespace */
      struct namespace *newNameSpaces
        = xmalloc((namespacesSize + 1) * sizeof (namespaces[0]));
      memcpy(newNameSpaces, namespaces, sizeof (namespaces[0]));
      namespaces = newNameSpaces;
      ++namespacesSize;
      newNamespaceID = 1;
    }
  else if (namespacesSize < NUM_NAMESPACES)
    {
      /* make room for additional namespace */
      newNamespaceID = namespacesSize;
      namespaces
        = xrealloc(namespaces, (namespacesSize + 1) * sizeof (namespaces[0]));
      ++namespacesSize;
    }
  else /* implicit: namespacesSize >= NUM_NAMESPACES */
    {
      NAMESPACE_UNLOCK();
      return -1;
    }
  xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
  ++nNamespaces;
  namespaces[newNamespaceID].hasLocalFiles = hasLocalFiles;
  namespaces[newNamespaceID].resStage = STAGE_DEFINITION;
168
169
170
  memcpy(namespaces[newNamespaceID].switches,
         (void *[NUM_NAMESPACE_SWITCH])defaultSwitches,
         sizeof (namespaces[newNamespaceID].switches));
Thomas Jahns's avatar
Thomas Jahns committed
171
172
173
  reshListCreate(newNamespaceID);
  NAMESPACE_UNLOCK();
  return newNamespaceID;
174
175
}

Thomas Jahns's avatar
Thomas Jahns committed
176
177
178
179
180
181
182
183
184
185
void
namespaceDelete(int namespaceID)
{
  NAMESPACE_LOCK();
  xassert(namespaceID < namespacesSize && nNamespaces);
  reshListDestruct(namespaceID);
  namespaces[namespaceID].resStage = STAGE_UNUSED;
  --nNamespaces;
  NAMESPACE_UNLOCK();
}
186

Deike Kleberg's avatar
Deike Kleberg committed
187
void namespaceCleanup ( void )
188
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
  if ( nNamespaces > 1 )
190
    {
Thomas Jahns's avatar
Thomas Jahns committed
191
      initialNamespace = namespaces[0];
192
193
194
      free(namespaces);
      namespaces = &initialNamespace;
      nNamespaces = 1;
195
    }
196
197
}

198

199
200
201
202
203
204
int namespaceGetNumber ()
{
  return nNamespaces;
}


205
void pioNamespaceSetActive ( int nId )
206
{
Thomas Jahns's avatar
Thomas Jahns committed
207
208
  xassert(nId < namespacesSize && nId >= 0
          && namespaces[nId].resStage != STAGE_UNUSED);
209
210
211
  activeNamespace = nId;
}

212

213
214
215
216
int namespaceGetActive ()
{
  return activeNamespace;
}
217
218
219
220


int namespaceHasLocalFile ( int nId )
{
Thomas Jahns's avatar
Thomas Jahns committed
221
  xassert(nId < namespacesSize && nId >= 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222

223
  return namespaces ? namespaces[nId].hasLocalFiles : 0;
224
}
225
226
227
228
229
230
231
232
233
234
235
236


int namespaceAdaptKey ( int key, int nspTarget )
{
  namespaceTuple_t tin;
  int nsp;

  if ( key == CDI_UNDEFID ) return CDI_UNDEFID;

  tin.idx = key & idxmask;
  tin.nsp = (int)(((unsigned)( key & nspmask )) >> idxbits);

Deike Kleberg's avatar
Deike Kleberg committed
237
  xassert ( tin.nsp == nspTarget );
238
239

  nsp = namespaceGetActive ();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240

241
242
  return namespaceIdxEncode2 ( nsp, tin.idx );
}
Deike Kleberg's avatar
Deike Kleberg committed
243
244
245
246
247
248
249
250
251
252
253
254
255


int namespaceAdaptKey2 ( int key )
{
  namespaceTuple_t tin;
  int nsp;

  if ( key == CDI_UNDEFID ) return CDI_UNDEFID;

  tin.idx = key & idxmask;
  tin.nsp = (int)(((unsigned)( key & nspmask )) >> idxbits);

  nsp = namespaceGetActive ();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256

Deike Kleberg's avatar
Deike Kleberg committed
257
258
259
  return namespaceIdxEncode2 ( nsp, tin.idx );
}

260

261
void namespaceDefResStatus ( statusCode argResStatus )
262
263
{
  int nsp = namespaceGetActive ();
264
  namespaces[nsp].resStage = argResStatus;
265
266
267
}


268
statusCode namespaceInqResStatus ( void )
269
270
{
  int nsp = namespaceGetActive ();
271
  return namespaces[nsp].resStage;
272
273
}

274
275
276
277
278
279
280
281
282
283
284
285
286
287
void namespaceSwitchSet(enum namespaceSwitch sw, void *value)
{
  xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
  int nsp = namespaceGetActive();
  namespaces[nsp].switches[sw] = value;
}

void *namespaceSwitchGet(enum namespaceSwitch sw)
{
  xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
  int nsp = namespaceGetActive();
  return namespaces[nsp].switches[sw];
}

Thomas Jahns's avatar
Thomas Jahns committed
288
289
290
291
292
293
294
295
296
297
298
299
void cdiReset(void)
{
  NAMESPACE_LOCK();
  for (int namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
    namespaceDelete(namespaceID);
  namespaces = &initialNamespace;
  namespacesSize = 1;
  nNamespaces = 1;
  activeNamespace = 0;
  NAMESPACE_UNLOCK();
}

300
301
302
303
304
305
306
307
308
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */