namespace.c 6.78 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"
13

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

17
18
19
20
21
22
#ifdef HAVE_LIBNETCDF
#define CDI_NETCDF_SWITCHES nc__create,cdf_def_var_serial,
#else
#define CDI_NETCDF_SWITCHES
#endif

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

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

struct namespace *namespaces = &initialNamespace;
50

Thomas Jahns's avatar
Thomas Jahns committed
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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


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

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

82

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

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


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

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

114

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

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

  return tin;
}

Thomas Jahns's avatar
Thomas Jahns committed
125
126
int
namespaceNew(int hasLocalFiles)
127
{
Thomas Jahns's avatar
Thomas Jahns committed
128
129
130
  int newNamespaceID = -1;
  NAMESPACE_LOCK();
  if (namespacesSize > nNamespaces)
131
    {
Thomas Jahns's avatar
Thomas Jahns committed
132
133
134
135
136
137
138
      /* namespace is already available and only needs reinitialization */
      for (int i = 0; i < namespacesSize; ++i)
        if (namespaces[i].resStage == STAGE_UNUSED)
          {
            newNamespaceID = i;
            break;
          }
139
    }
Thomas Jahns's avatar
Thomas Jahns committed
140
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
  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;
167
168
169
  memcpy(namespaces[newNamespaceID].switches,
         (void *[NUM_NAMESPACE_SWITCH])defaultSwitches,
         sizeof (namespaces[newNamespaceID].switches));
Thomas Jahns's avatar
Thomas Jahns committed
170
171
172
  reshListCreate(newNamespaceID);
  NAMESPACE_UNLOCK();
  return newNamespaceID;
173
174
}

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

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

197

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


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

211

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


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

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


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
236
  xassert ( tin.nsp == nspTarget );
237
238

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

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


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
255

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

259

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


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

273
274
275
276
277
278
279
280
281
282
283
284
285
286
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
287
288
289
290
291
292
293
294
295
296
297
298
void cdiReset(void)
{
  NAMESPACE_LOCK();
  for (int namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
    namespaceDelete(namespaceID);
  namespaces = &initialNamespace;
  namespacesSize = 1;
  nNamespaces = 1;
  activeNamespace = 0;
  NAMESPACE_UNLOCK();
}

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