~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/libs/cull/cull_db.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
10
 *  Sun Industry Standards Source License Version 1.2
 
11
 *  =================================================
 
12
 *  The contents of this file are subject to the Sun Industry Standards
 
13
 *  Source License Version 1.2 (the "License"); You may not use this file
 
14
 *  except in compliance with the License. You may obtain a copy of the
 
15
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
16
 * 
 
17
 *  Software provided under this License is provided on an "AS IS" basis,
 
18
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
19
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
20
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
21
 *  See the License for the specific provisions governing your rights and
 
22
 *  obligations concerning the Software.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
 
 
36
/* do not compile in monitoring code */
 
37
#ifndef NO_SGE_COMPILE_DEBUG
 
38
#define NO_SGE_COMPILE_DEBUG
 
39
#endif
 
40
 
 
41
#include "sgermon.h"
 
42
#include "cull_db.h"
 
43
#include "cull_where.h"
 
44
#include "cull_listP.h"
 
45
#include "cull_whatP.h"
 
46
#include "cull_multitypeP.h"
 
47
#include "cull_lerrnoP.h"
 
48
#include "cull_hash.h"
 
49
#include "sge_string.h"
 
50
#include "cull_pack.h"
 
51
#include "pack.h"
 
52
 
 
53
static lListElem *lJoinCopyElem(const lDescr *dp, 
 
54
                                const lListElem *sep0, 
 
55
                                const lEnumeration *ep0, 
 
56
                                const lListElem *sep1, 
 
57
                                const lEnumeration *ep1);
 
58
 
 
59
/****** cull/db/lJoinCopyElem() ***********************************************
 
60
*  NAME
 
61
*     lJoinCopyElem() -- Combine two elements 
 
62
*
 
63
*  SYNOPSIS
 
64
*     static lListElem* lJoinCopyElem(const lDescr *dp, 
 
65
*                                     const lListElem *src0, 
 
66
*                                     const lEnumeration *enp0, 
 
67
*                                     const lListElem *src1, 
 
68
*                                     const lEnumeration *enp1) 
 
69
*
 
70
*  FUNCTION
 
71
*     Returns a combined element with descriptor 'dp'. Uses 'src0'
 
72
*     with mask 'enp0' and 'src1' with mask 'enp1' as source. 
 
73
*
 
74
*  INPUTS
 
75
*     const lDescr *dp         - descriptor 
 
76
*     const lListElem *src0    - element1 
 
77
*     const lEnumeration *enp0 - mask1 
 
78
*     const lListElem *src1    - element2 
 
79
*     const lEnumeration *enp1 - mask2 
 
80
*
 
81
*  RESULT
 
82
*     static lListElem* - combined element 
 
83
******************************************************************************/
 
84
static lListElem *lJoinCopyElem(const lDescr *dp, 
 
85
                                const lListElem *src0,
 
86
                                const lEnumeration *enp0,
 
87
                                const lListElem *src1,
 
88
                                const lEnumeration *enp1) 
 
89
{
 
90
   lListElem *dst;
 
91
   int i;
 
92
 
 
93
   DENTER(CULL_LAYER, "lJoinCopyElem");
 
94
 
 
95
   if (!src0 || !src1) {
 
96
      LERROR(LEELEMNULL);
 
97
      DEXIT;
 
98
      return NULL;
 
99
   }
 
100
 
 
101
   if (!(dst = lCreateElem(dp))) {
 
102
      LERROR(LECREATEELEM);
 
103
      DEXIT;
 
104
      return NULL;
 
105
   }
 
106
 
 
107
   i = 0;
 
108
   if (lCopyElemPartialPack(dst, &i, src0, enp0, true, NULL) == -1) {
 
109
      free(dst);
 
110
      LERROR(LECOPYELEMPART);
 
111
      DEXIT;
 
112
      return NULL;
 
113
   }
 
114
   if (lCopyElemPartialPack(dst, &i, src1, enp1, true, NULL) == -1) {
 
115
      free(dst);
 
116
      LERROR(LECOPYELEMPART);
 
117
      DEXIT;
 
118
      return NULL;
 
119
   }
 
120
 
 
121
   DEXIT;
 
122
   return dst;
 
123
}
 
124
 
 
125
/****** cull/db/lJoinSublist() ************************************************
 
126
*  NAME
 
127
*     lJoinSublist() -- Join a list with one of its sublists 
 
128
*
 
129
*  SYNOPSIS
 
130
*     lList* lJoinSublist(const char *name, 
 
131
*                         int nm0, 
 
132
*                         const lList *lp, 
 
133
*                         const lCondition *cp0, 
 
134
*                         const lEnumeration *enp0, 
 
135
*                         const lDescr *sldp, 
 
136
*                         const lCondition *cp1, 
 
137
*                         const lEnumeration *enp1) 
 
138
*
 
139
*  FUNCTION
 
140
*     Joins a list and one of its sublists together. The other 
 
141
*     parameters are equal to them from lJoin(). In the enumeration
 
142
*     'enp0' the sublist field neither may be selected nor 'enp0'
 
143
*     may be NULL. 
 
144
*
 
145
*  INPUTS
 
146
*     const char *name         - new list name 
 
147
*     int nm0                  - 
 
148
*     const lList *lp          - list 
 
149
*     const lCondition *cp0    - selects rows within 'lp' 
 
150
*     const lEnumeration *enp0 - selects columns within 'lp' 
 
151
*     const lDescr *sldp       - sublist descriptor pointer 
 
152
*     const lCondition *cp1    - selects rows within 'sldp' 
 
153
*     const lEnumeration *enp1 - selects columns within 'enp1' 
 
154
*
 
155
*  RESULT
 
156
*     lList* - Joined list 
 
157
******************************************************************************/
 
158
lList *lJoinSublist(const char *name, int nm0, const lList *lp, 
 
159
                    const lCondition *cp0, const lEnumeration *enp0,
 
160
                    const lDescr *sldp, const lCondition *cp1, 
 
161
                    const lEnumeration *enp1) 
 
162
{
 
163
   lList *dlp, *tlp, *joinedlist, *sublist;
 
164
   lListElem *ep;
 
165
   lDescr *dp; 
 
166
   const lDescr *tdp;
 
167
   int i, pos;
 
168
 
 
169
   DENTER(CULL_LAYER, "lJoinSublist");
 
170
 
 
171
   /* check different pointers */
 
172
   if (!name || !lp || !enp0 || !sldp || !enp1) {
 
173
      LERROR(LENULLARGS);
 
174
      DEXIT;
 
175
      return NULL;
 
176
   }
 
177
 
 
178
   /* make sure that nm0 is a sublist field of lp */
 
179
   if (!(tdp = lGetListDescr(lp))) {
 
180
      LERROR(LEDESCRNULL);
 
181
      DEXIT;
 
182
      return NULL;
 
183
   }
 
184
   if ((pos = lGetPosInDescr(tdp, nm0)) < 0) {
 
185
      LERROR(LENAMENOT);
 
186
      DEXIT;
 
187
      return NULL;
 
188
   }
 
189
 
 
190
   if (mt_get_type(tdp[pos].mt) != lListT) {
 
191
      LERROR(LEINCTYPE);
 
192
      DEXIT;
 
193
      return NULL;
 
194
   }
 
195
 
 
196
   /* is nm0 enumerated in enp0 ? */
 
197
   if (enp0[0].pos == WHAT_ALL) {
 
198
      LERROR(LEFALSEFIELD);
 
199
      DEXIT;
 
200
      return NULL;
 
201
   }
 
202
   for (i = 0; enp0[i].nm != NoName; i++)
 
203
      if (enp0[i].nm == nm0) {
 
204
         LERROR(LEFALSEFIELD);
 
205
         DEXIT;
 
206
         return NULL;
 
207
      }
 
208
 
 
209
   /* create destination list */
 
210
   if (!(dp = lJoinDescr(lGetListDescr(lp), sldp, enp0, enp1))) {
 
211
      LERROR(LEJOINDESCR);
 
212
      DEXIT;
 
213
      return NULL;
 
214
   }
 
215
   if (!(dlp = lCreateList(name, dp))) {
 
216
      free(dp);
 
217
      LERROR(LECREATELIST);
 
218
      DEXIT;
 
219
      return NULL;
 
220
   }
 
221
   /* free dp it has been copied in lCreateList */
 
222
   free(dp);
 
223
 
 
224
   /* create a temporary list to be used by lJoin */
 
225
   if (!(tlp = lCreateList("lJoinSublist: tlp", lGetListDescr(lp)))) {
 
226
      lFreeList(&dlp);
 
227
      LERROR(LECREATELIST);
 
228
      DEXIT;
 
229
      return NULL;
 
230
   }
 
231
 
 
232
   for_each_where(ep, lp, cp0) {
 
233
      /* is there a sublist for the join */
 
234
      if ((sublist = lGetList(ep, nm0)) != NULL) {
 
235
 
 
236
         /* put each element in the tlp to be used by lJoin */
 
237
         if (lAppendElem(tlp, lCopyElem(ep)) == -1) {
 
238
            lFreeList(&tlp);
 
239
            lFreeList(&dlp);
 
240
            LERROR(LEAPPENDELEM);
 
241
            DEXIT;
 
242
            return NULL;
 
243
         }
 
244
 
 
245
         /* join the tlp with one element together with its sublist */
 
246
         joinedlist = lJoin("lJoinSublist: joinedlist", nm0, tlp, NULL, enp0,
 
247
                            NoName, sublist, cp1, enp1);
 
248
 
 
249
         if (!joinedlist) {
 
250
            lFreeList(&tlp);
 
251
            lFreeList(&dlp);
 
252
            LERROR(LEJOIN);
 
253
            DEXIT;
 
254
            return NULL;
 
255
         }
 
256
 
 
257
         /* joinedlist is freed in lAddList */
 
258
         if (joinedlist && lAddList(dlp, &joinedlist) == -1) {
 
259
            LERROR(LEADDLIST);
 
260
            lFreeList(&tlp);
 
261
            lFreeList(&dlp);
 
262
            DEXIT;
 
263
            return NULL;
 
264
         }
 
265
 
 
266
         /* dechain the only element from tlp and free it (copy) */
 
267
         lRemoveElem(tlp, &(tlp->first));
 
268
      }
 
269
   }
 
270
   /* temporary list has to be freed */
 
271
   lFreeList(&tlp);
 
272
 
 
273
   /* RETURN AN EMPTY LIST OR NULL THAT'S THE QUESTION */
 
274
 
 
275
   if (lGetNumberOfElem(dlp) == 0) {
 
276
      lFreeList(&dlp);
 
277
   }
 
278
 
 
279
   DEXIT;
 
280
   return dlp;
 
281
}
 
282
 
 
283
/****** cull/db/lJoin() *******************************************************
 
284
*  NAME
 
285
*     lJoin() -- Joins two lists together
 
286
*
 
287
*  SYNOPSIS
 
288
*     lList* lJoin(const char *name, int nm0, const lList *lp0, 
 
289
*                  const lCondition *cp0, const lEnumeration *enp0, 
 
290
*                  int nm1, const lList *lp1, const lCondition *cp1, 
 
291
*                  const lEnumeration *enp1) 
 
292
*
 
293
*  FUNCTION
 
294
*     Returns a new list joining together the lists 'lp0' and 'lp1'
 
295
*     For the join only these 'lines' described in condition 'cp0'
 
296
*     and 'cp1' are used.
 
297
*     The new list gets only these members described in 'enp0' and
 
298
*     'enp1'. NULL means every member of this list.
 
299
*     The list gets 'name' as listname.
 
300
*
 
301
*  INPUTS
 
302
*     const char *name         - name of new list 
 
303
*     int nm0                  - 
 
304
*     const lList *lp0         - first list 
 
305
*     const lCondition *cp0    - selects rows of first list 
 
306
*     const lEnumeration *enp0 - selects column of first list 
 
307
*     int nm1                  - 
 
308
*     const lList *lp1         - second list 
 
309
*     const lCondition *cp1    - selects rows of second list 
 
310
*     const lEnumeration *enp1 - selects column of seconf list 
 
311
*
 
312
*  RESULT
 
313
*     lList* - Joined list 
 
314
******************************************************************************/
 
315
lList *lJoin(const char *name, int nm0, const lList *lp0, 
 
316
             const lCondition *cp0, const lEnumeration *enp0, int nm1,
 
317
             const lList *lp1, const lCondition *cp1, const lEnumeration *enp1)
 
318
{
 
319
   lListElem *ep0, *ep1;
 
320
   lListElem *ep;
 
321
   lList *dlp = NULL;
 
322
   lDescr *dp;
 
323
   int lp0_pos = 0, lp1_pos = 0;
 
324
   int i, j;
 
325
   int needed;
 
326
 
 
327
   DENTER(CULL_LAYER, "lJoin");
 
328
 
 
329
   if (!lp0 || !lp1 || !name || !enp0 || !enp1) {
 
330
      LERROR(LENULLARGS);
 
331
      DEXIT;
 
332
      return NULL;
 
333
   }
 
334
 
 
335
   if (nm1 != NoName) {
 
336
      if ((lp0_pos = lGetPosInDescr(lGetListDescr(lp0), nm0)) < 0) {
 
337
         LERROR(LENAMENOT);
 
338
         DEXIT;
 
339
         return NULL;
 
340
      }
 
341
      if ((lp1_pos = lGetPosInDescr(lGetListDescr(lp1), nm1)) < 0) {
 
342
         LERROR(LENAMENOT);
 
343
         DEXIT;
 
344
         return NULL;
 
345
      }
 
346
 
 
347
      if (mt_get_type(lp0->descr[lp0_pos].mt) != mt_get_type(lp1->descr[lp1_pos].mt) ||
 
348
          mt_get_type(lp0->descr[lp0_pos].mt) == lListT) {
 
349
         LERROR(LEDIFFDESCR);
 
350
         DEXIT;
 
351
         return NULL;
 
352
      }
 
353
   }
 
354
 
 
355
   /* the real join ?! */
 
356
   if (!(dp = lJoinDescr(lGetListDescr(lp0), lGetListDescr(lp1), enp0, enp1))) {
 
357
      LERROR(LEJOINDESCR);
 
358
      DEXIT;
 
359
      return NULL;
 
360
   }
 
361
   if (!(dlp = lCreateList(name, dp))) {
 
362
      LERROR(LECREATELIST);
 
363
      free(dp);
 
364
      DEXIT;
 
365
      return NULL;
 
366
   }
 
367
   /* free dp it has been copied by lCreateList */
 
368
   free(dp);
 
369
 
 
370
   for (i = 0, ep0 = lp0->first; i < lp0->nelem; i++, ep0 = ep0->next) {
 
371
      if (!lCompare(ep0, cp0))
 
372
         continue;
 
373
      for (j = 0, ep1 = lp1->first; j < lp1->nelem; j++, ep1 = ep1->next) {
 
374
         if (!lCompare(ep1, cp1))
 
375
            continue;
 
376
         if (nm1 != NoName) {   /* in this case take it always */
 
377
            /* This is a comparison of the join fields nm0 , nm1 */
 
378
            switch (mt_get_type(lp0->descr[lp0_pos].mt)) {
 
379
            case lIntT:
 
380
               needed = (ep0->cont[lp0_pos].i == ep1->cont[lp1_pos].i);
 
381
               break;
 
382
            case lUlongT:
 
383
               needed = (ep0->cont[lp0_pos].ul == ep1->cont[lp1_pos].ul);
 
384
               break;
 
385
            case lStringT:
 
386
               needed = !strcmp(ep0->cont[lp0_pos].str, ep1->cont[lp1_pos].str);
 
387
               break;
 
388
            case lHostT:
 
389
               needed = !strcmp(ep0->cont[lp0_pos].str, ep1->cont[lp1_pos].str);
 
390
               break;
 
391
            case lLongT:
 
392
               needed = (ep0->cont[lp0_pos].l == ep1->cont[lp1_pos].l);
 
393
               break;
 
394
            case lFloatT:
 
395
               needed = (ep0->cont[lp0_pos].fl == ep1->cont[lp1_pos].fl);
 
396
               break;
 
397
            case lDoubleT:
 
398
               needed = (ep0->cont[lp0_pos].db == ep1->cont[lp1_pos].db);
 
399
               break;
 
400
            case lCharT:
 
401
               needed = (ep0->cont[lp0_pos].c == ep1->cont[lp1_pos].c);
 
402
               break;
 
403
            case lBoolT:
 
404
               needed = (ep0->cont[lp0_pos].b == ep1->cont[lp1_pos].b);
 
405
               break;
 
406
            case lRefT:
 
407
               needed = (ep0->cont[lp0_pos].ref == ep1->cont[lp1_pos].ref);
 
408
               break;
 
409
            default:
 
410
               unknownType("lJoin");
 
411
               DEXIT;
 
412
               return NULL;
 
413
            }
 
414
            if (!needed)
 
415
               continue;
 
416
         }
 
417
         if (!(ep = lJoinCopyElem(dlp->descr, ep0, enp0, ep1, enp1))) {
 
418
            LERROR(LEJOINCOPYELEM);
 
419
            lFreeList(&dlp);
 
420
            DEXIT;
 
421
            return NULL;
 
422
         }
 
423
         else {
 
424
            if (lAppendElem(dlp, ep) == -1) {
 
425
               LERROR(LEAPPENDELEM);
 
426
               lFreeList(&dlp);
 
427
               DEXIT;
 
428
               return NULL;
 
429
            }
 
430
         }
 
431
      }
 
432
   }
 
433
 
 
434
   /* RETURN AN EMPTY LIST OR NULL THAT'S THE QUESTION */
 
435
 
 
436
   if (lGetNumberOfElem(dlp) == 0) {
 
437
      lFreeList(&dlp);
 
438
   }
 
439
 
 
440
   DEXIT;
 
441
   return dlp;
 
442
}
 
443
 
 
444
/****** cull/db/lSplit() ******************************************************
 
445
*  NAME
 
446
*     lSplit() -- Splits a list into two list 
 
447
*
 
448
*  SYNOPSIS
 
449
*     int lSplit(lList **slp, lList **ulp, const char *ulp_name, 
 
450
*                const lCondition *cp) 
 
451
*
 
452
*  FUNCTION
 
453
*     Unchains the list elements from the list 'slp' NOT fullfilling
 
454
*     the condition 'cp' and returns a list containing the 
 
455
*     unchained elements in 'ulp' 
 
456
*
 
457
*  INPUTS
 
458
*     lList **slp          - source list pointer 
 
459
*     lList **ulp          - unchained list pointer 
 
460
*     const char *ulp_name - 'ulp' list name 
 
461
*     const lCondition *cp - selects rows within 'slp' 
 
462
*
 
463
*  RESULT
 
464
*     int - error status
 
465
*         0 - OK
 
466
*        -1 - Error 
 
467
******************************************************************************/
 
468
int lSplit(lList **slp, lList **ulp, const char *ulp_name, 
 
469
           const lCondition *cp) 
 
470
{
 
471
 
 
472
   lListElem *ep, *next;
 
473
   int has_been_allocated = 0;
 
474
 
 
475
   DENTER(TOP_LAYER, "lSplit");
 
476
 
 
477
   /*
 
478
      iterate through the source list call lCompare and chain all elems
 
479
      that don't fullfill the condition into a new list.
 
480
    */
 
481
   if (!slp) {
 
482
      DEXIT;
 
483
      return -1;
 
484
   }
 
485
 
 
486
   for (ep = lFirst(*slp); ep; ep = next) {
 
487
      next = ep->next;          /* this is important, cause the elem is dechained */
 
488
 
 
489
      if (!lCompare(ep, cp)) {
 
490
         if (ulp && !*ulp) {
 
491
            *ulp = lCreateList(ulp_name ? ulp_name : "ulp", (*slp)->descr);
 
492
            if (!*ulp) {
 
493
               DEXIT;
 
494
               return -1;
 
495
            }
 
496
            has_been_allocated = 1;
 
497
         }
 
498
         if (ulp) {
 
499
            ep = lDechainElem(*slp, ep);
 
500
            lAppendElem(*ulp, ep);
 
501
         } else {
 
502
            lRemoveElem(*slp, &ep);
 
503
         }
 
504
      }
 
505
   }
 
506
 
 
507
   /* if no elements remain, free the list and return NULL */
 
508
   if (*slp && lGetNumberOfElem(*slp) == 0) {
 
509
      lFreeList(slp);
 
510
   }
 
511
   if (has_been_allocated && *ulp && lGetNumberOfElem(*ulp) == 0) {
 
512
      lFreeList(ulp);
 
513
   }
 
514
 
 
515
   DEXIT;
 
516
   return 0;
 
517
}
 
518
 
 
519
/****** cull/db/lSelectDestroy() **********************************************
 
520
*  NAME
 
521
*     lSelectDestroy() -- Removes the not needed list elements 
 
522
*
 
523
*  SYNOPSIS
 
524
*     lList* lSelectDestroy(lList *slp, const lCondition *cp) 
 
525
*
 
526
*  FUNCTION
 
527
*     Removes the not needed list elements from the list 'slp' NOT
 
528
*     fulfilling the condition 'cp' 
 
529
*
 
530
*  INPUTS
 
531
*     lList *slp           - source list pointer 
 
532
*     const lCondition *cp - selects rows 
 
533
*
 
534
*  RESULT
 
535
*     lList* - List with the remaining elements 
 
536
******************************************************************************/
 
537
lList *lSelectDestroy(lList *slp, const lCondition *cp) 
 
538
{
 
539
 
 
540
   DENTER(CULL_LAYER, "lSelectDestroy");
 
541
 
 
542
   if (lSplit(&slp, NULL, NULL, cp)) {
 
543
      lFreeList(&slp);
 
544
      DEXIT;
 
545
      return NULL;
 
546
   }
 
547
   DEXIT;
 
548
   return slp;
 
549
}
 
550
 
 
551
/****** cull/db/lSelectElemPack() *********************************************
 
552
*  NAME
 
553
*     lSelectElemPack() -- Extracts some elements fulfilling a condition 
 
554
*
 
555
*  SYNOPSIS
 
556
*     lListElem* 
 
557
*     lSelectElemPack(const lListElem *slp, const lCondition *cp, 
 
558
*                     const lEnumeration *enp, bool isHash, 
 
559
*                     sge_pack_buffer *pb) 
 
560
*
 
561
*  FUNCTION
 
562
*     Creates a new list from the list 'slp' extracting the elements
 
563
*     fulfilling the condition 'cp' or extracts the elements and
 
564
*     stores the contend in 'pb'. 
 
565
*
 
566
*  INPUTS
 
567
*     const lListElem *slp    - source list pointer 
 
568
*     const lCondition *cp    - selects rows 
 
569
*     const lEnumeration *enp - selects columns 
 
570
*     bool isHash             - create hash or not
 
571
*     sge_pack_buffer *pb     - packbuffer
 
572
*
 
573
*  RESULT
 
574
*     lListElem* - list containing the extracted elements
 
575
******************************************************************************/
 
576
lListElem *
 
577
lSelectElemPack(const lListElem *slp, const lCondition *cp,
 
578
                const lEnumeration *enp, bool isHash, sge_pack_buffer *pb) 
 
579
{
 
580
   lListElem *new = NULL;
 
581
 
 
582
   DENTER(CULL_LAYER, "lSelectElemPack");
 
583
 
 
584
   if (!slp) {
 
585
      DEXIT;
 
586
      return NULL;
 
587
   }
 
588
   if (enp != NULL) {
 
589
      lDescr *dp;
 
590
      int n, index = 0;
 
591
      u_long32 elements = 0;
 
592
 
 
593
      /* create new lList with partial descriptor */
 
594
      if ((n = lCountWhat(enp, slp->descr)) <= 0) {
 
595
         LERROR(LECOUNTWHAT);
 
596
         DEXIT;
 
597
         return NULL;
 
598
      }
 
599
      if (!(dp = (lDescr *) malloc(sizeof(lDescr) * (n + 1)))) {
 
600
         LERROR(LEMALLOC);
 
601
         DEXIT;
 
602
         return NULL;
 
603
      }
 
604
      /* INITIALIZE THE INDEX IF YOU BUILD A NEW DESCRIPTOR */
 
605
      if (lPartialDescr(enp, slp->descr, dp, &index) < 0) {
 
606
         LERROR(LEPARTIALDESCR);
 
607
         free(dp);
 
608
         DEXIT;
 
609
         return NULL;
 
610
      }
 
611
      /* create reduced element */
 
612
      new = lSelectElemDPack(slp, cp, dp, enp, isHash, pb, &elements);
 
613
      /* free the descriptor, it has been copied by lCreateList */
 
614
      cull_hash_free_descr(dp);
 
615
      free(dp);
 
616
   } else {
 
617
      /* no enumeration => make a copy of element */
 
618
      new = lCopyElemHash(slp, isHash);
 
619
   }
 
620
   DEXIT;
 
621
   return new;
 
622
}
 
623
 
 
624
/****** cull/db/lSelectElemDPack() ********************************************
 
625
*  NAME
 
626
*     lSelectElemDPack() -- Extracts some elements fulfilling a condition 
 
627
*
 
628
*  SYNOPSIS
 
629
*     lListElem* 
 
630
*     lSelectElemDPack(const lListelem *slp, const lCondition *cp, 
 
631
*                      const lEnumeration *enp, bool isHash, 
 
632
*                      sge_pack_buffer *pb) 
 
633
*
 
634
*  FUNCTION
 
635
*     Creates a new list from the list 'slp' extracting the elements
 
636
*     fulfilling the condition 'cp' or it packs those elemets into 'pb' if 
 
637
*     it is not NULL. 
 
638
*
 
639
*  INPUTS
 
640
*     const lListElem *slp     - source list pointer 
 
641
*     const lCondition *cp     - selects rows 
 
642
*     const lDescr *dp         - target descriptor for the element
 
643
*     bool  isHash             - creates hash or not
 
644
*     sge_pack_buffer *pb      - packbuffer
 
645
*     u_long32 *elements       - increases the number of elems, if one is
 
646
*                                added to the pb. Only, when elements is 
 
647
*                                not NULL (only used if pb != NULL)
 
648
*
 
649
*  RESULT
 
650
*     lListElem* - list containing the extracted elements
 
651
******************************************************************************/
 
652
lListElem *
 
653
lSelectElemDPack(const lListElem *slp, const lCondition *cp, const lDescr *dp, 
 
654
                 const lEnumeration *enp, bool isHash, sge_pack_buffer *pb,
 
655
                 u_long32 *elements) 
 
656
{
 
657
   lListElem *new = NULL;
 
658
   int index = 0;
 
659
 
 
660
   DENTER(CULL_LAYER, "lSelectElemDPack");
 
661
   if (!slp || (!dp && !pb)) {
 
662
      DEXIT;
 
663
      return NULL;
 
664
   }
 
665
   /*
 
666
    * iterate through the source list call lCompare and add
 
667
    * depending on result of lCompare
 
668
    */
 
669
   if (lCompare(slp, cp)) {
 
670
      if (pb == NULL) {
 
671
         if (!(new = lCreateElem(dp))) {
 
672
            DEXIT;
 
673
            return NULL;
 
674
         }
 
675
         
 
676
         if (lCopyElemPartialPack(new, &index, slp, enp, isHash, pb)) {
 
677
            lFreeElem(&new);
 
678
         }
 
679
      } else {
 
680
         if (elements != NULL) {
 
681
            (*elements)++;
 
682
         }
 
683
 
 
684
         lCopyElemPartialPack(NULL, &index, slp, enp, isHash, pb);
 
685
         new = NULL;
 
686
      }
 
687
   }
 
688
   DEXIT;
 
689
   return new;
 
690
}
 
691
 
 
692
/****** cull/db/lSelect() *****************************************************
 
693
*  NAME
 
694
*     lSelect() -- Extracts some elements fulfilling a condition 
 
695
*
 
696
*  SYNOPSIS
 
697
*     lList* lSelect(const char *name, const lList *slp, 
 
698
*                    const lCondition *cp, const lEnumeration *enp) 
 
699
*
 
700
*  FUNCTION
 
701
*     Creates a new list from the list 'slp' extracting the elements
 
702
*     fulfilling the condition 'cp'. 
 
703
*
 
704
*  INPUTS
 
705
*     const char *name        - name for the new list 
 
706
*     const lList *slp        - source list pointer 
 
707
*     const lCondition *cp    - selects rows 
 
708
*     const lEnumeration *enp - selects columns 
 
709
*
 
710
*  RESULT
 
711
*     lList* - list containing the extracted elements
 
712
******************************************************************************/
 
713
lList *lSelect(const char *name, const lList *slp, const lCondition *cp,
 
714
               const lEnumeration *enp) {
 
715
   return lSelectHashPack(name, slp, cp, enp, true, NULL);               
 
716
}               
 
717
 
 
718
/****** cull/db/lSelectHashPack() *********************************************
 
719
*  NAME
 
720
*     lSelectHashPack() -- Extracts some elements fulfilling a condition 
 
721
*
 
722
*  SYNOPSIS
 
723
*     lList* 
 
724
*     lSelectHashPack(const char *name, const lList *slp, 
 
725
*                     const lCondition *cp, const lEnumeration *enp, 
 
726
*                     bool isHash, sge_pack_buffer *pb) 
 
727
*
 
728
*  FUNCTION
 
729
*     Creates a new list from the list 'slp' extracting the elements
 
730
*     fulfilling the condition 'cp' or fills the packbuffer if pb is 
 
731
*     not NULL.
 
732
*
 
733
*  INPUTS
 
734
*     const char *name        - name for the new list 
 
735
*     const lList *slp        - source list pointer 
 
736
*     const lCondition *cp    - selects rows 
 
737
*     const lEnumeration *enp - selects columns 
 
738
*     bool  isHash            - enables/disables the hash generation
 
739
*     sge_pack_buffer *pb     - packbuffer
 
740
*
 
741
*  RESULT
 
742
*     lList* - list containing the extracted elements
 
743
******************************************************************************/
 
744
lList *lSelectHashPack(const char *name, const lList *slp, 
 
745
                       const lCondition *cp, const lEnumeration *enp, 
 
746
                       bool isHash, sge_pack_buffer *pb) 
 
747
{
 
748
   lList *ret = NULL;
 
749
 
 
750
   DENTER(CULL_LAYER, "lSelectHashPack");
 
751
   if (slp == NULL && pb == NULL) {
 
752
      DEXIT;
 
753
      return NULL;
 
754
   }
 
755
 
 
756
   if (enp != NULL) {
 
757
      if (pb == NULL) {
 
758
         lDescr *dp;
 
759
         int n, index;
 
760
 
 
761
         /* create new lList with partial descriptor */
 
762
         n = lCountWhat(enp, slp->descr);
 
763
         if (n <= 0) {
 
764
            LERROR(LECOUNTWHAT);
 
765
            DEXIT;
 
766
            return NULL;
 
767
         }
 
768
 
 
769
         dp = malloc(sizeof(lDescr) * (n + 1));
 
770
         if (dp == NULL) {
 
771
            LERROR(LEMALLOC);
 
772
            DEXIT;
 
773
            return NULL;
 
774
         }
 
775
 
 
776
         /* INITIALIZE THE INDEX IF YOU BUILD A NEW DESCRIPTOR */
 
777
         index = 0;
 
778
         if (lPartialDescr(enp, slp->descr, dp, &index) < 0) {
 
779
            LERROR(LEPARTIALDESCR);
 
780
            free(dp);
 
781
            DEXIT;
 
782
            return NULL;
 
783
         }
 
784
         ret = lSelectDPack(name, slp, cp, dp, enp, isHash, NULL, NULL);
 
785
 
 
786
         /* free the descriptor, it has been copied by lCreateList */
 
787
         cull_hash_free_descr(dp);
 
788
         free(dp);
 
789
      } else {
 
790
         u_long32 number_of_packed_elements = 0;
 
791
         size_t offset = 0;
 
792
         size_t used = 0;
 
793
         const char *pack_name = "";
 
794
         int local_ret;
 
795
 
 
796
         if (name != NULL) {
 
797
            pack_name = name;
 
798
         } else if (slp != NULL) {
 
799
            pack_name = slp->listname;
 
800
         }
 
801
 
 
802
         local_ret = cull_pack_list_summary(pb, slp, enp, pack_name, &offset, &used);
 
803
         if (local_ret != PACK_SUCCESS) {
 
804
            LERROR(LEMALLOC);
 
805
            DEXIT;
 
806
            return NULL;
 
807
         }
 
808
 
 
809
         lSelectDPack(name, slp, cp, NULL, enp, isHash, pb, 
 
810
                      &number_of_packed_elements);
 
811
  
 
812
         /*
 
813
          * change number of elements contained in the packbuffer 
 
814
          */
 
815
         if (slp != NULL && pb != NULL) {
 
816
            char *old_cur_ptr = NULL;
 
817
            size_t old_used = 0;
 
818
 
 
819
            old_cur_ptr = pb->cur_ptr;
 
820
            old_used = pb->bytes_used;
 
821
            pb->cur_ptr = pb->head_ptr + offset;
 
822
            pb->bytes_used = used;
 
823
 
 
824
            local_ret = repackint(pb, number_of_packed_elements);
 
825
            if(local_ret != PACK_SUCCESS) {
 
826
               LERROR(LEMALLOC);
 
827
               DEXIT;
 
828
               return NULL;
 
829
            }
 
830
            pb->cur_ptr = old_cur_ptr;
 
831
            pb->bytes_used = old_used;
 
832
         } 
 
833
      }
 
834
   } else {
 
835
      if (pb == NULL) {
 
836
         ret = lCopyListHash(slp->listname, slp, isHash);
 
837
      } else {
 
838
         cull_pack_list(pb, slp);
 
839
      }
 
840
   }
 
841
   DEXIT;
 
842
   return ret;
 
843
}
 
844
 
 
845
/****** cull_db/lSelectDPack() ************************************************
 
846
*  NAME
 
847
*     lSelectDPack() --  Extracts some elements fulfilling a condition 
 
848
*
 
849
*  SYNOPSIS
 
850
*     lList* lSelectDPack(const char *name, const lList *slp, 
 
851
*                         const lCondition *cp, const lDescr *dp, 
 
852
*                         bool isHash, sge_pack_buffer *pb) 
 
853
*
 
854
*
 
855
*  FUNCTION
 
856
*     Creates a new list from the list 'slp' extracting the elements
 
857
*     fulfilling the condition 'cp' or packs the elements into the
 
858
*     packbuffer 'pb' if it is not NULL. 
 
859
*
 
860
*  INPUTS
 
861
*     const char *name        - name for the new list 
 
862
*     const lList *slp        - source list pointer 
 
863
*     const lCondition *cp    - selects rows 
 
864
*     const lDescr *dp        - descriptor for the new list
 
865
*     const lEnumeration *enp - selects columns
 
866
*     bool  isHash            - enables/disables the hash table creation 
 
867
*     sge_pack_buffer *pb     - packbuffer
 
868
*     u_long32 *elements      - number of packed elements 
 
869
*                               (only used if pb != NULL)
 
870
*
 
871
*  RESULT
 
872
*     lList* - list containing the extracted elements
 
873
*******************************************************************************/
 
874
lList *lSelectDPack(const char *name, const lList *slp, const lCondition *cp,
 
875
                    const lDescr *dp, const lEnumeration *enp, bool isHash,
 
876
                    sge_pack_buffer *pb, u_long32 *elements) 
 
877
{
 
878
 
 
879
   lListElem *ep, *new;
 
880
   lList *dlp = (lList *) NULL;
 
881
   const lDescr *descr = NULL;
 
882
 
 
883
   DENTER(CULL_LAYER, "lSelectDPack");
 
884
 
 
885
   if (!slp || (!dp && !pb)) {
 
886
      DEXIT;
 
887
      return NULL;
 
888
   }
 
889
 
 
890
   if (pb == NULL) {
 
891
      if (!(dlp = lCreateListHash(name, dp, false))) {
 
892
         LERROR(LECREATELIST);
 
893
         DEXIT;
 
894
         return NULL;
 
895
      }
 
896
      dlp->changed = slp->changed;
 
897
      descr = dlp->descr;
 
898
   }
 
899
 
 
900
   /*
 
901
      iterate through the source list call lCompare and add
 
902
      depending on result of lCompare
 
903
    */
 
904
   for (ep = slp->first; ep; ep = ep->next) {
 
905
      new = lSelectElemDPack(ep, cp, descr, enp, isHash, pb, elements);
 
906
      if (new != NULL) {
 
907
         if (lAppendElem(dlp, new) == -1) {
 
908
            LERROR(LEAPPENDELEM);
 
909
            lFreeElem(&new);
 
910
            lFreeList(&dlp);
 
911
            DEXIT;
 
912
            return NULL;
 
913
         }
 
914
      }
 
915
   }
 
916
   
 
917
   if (pb == NULL && isHash) {
 
918
      /* now create the hash tables */
 
919
      cull_hash_create_hashtables(dlp);
 
920
 
 
921
      /* 
 
922
       * This is a question of philosophy.
 
923
       * To return an empty list or not to return.
 
924
       */
 
925
      if (lGetNumberOfElem(dlp) == 0) {
 
926
         LERROR(LEGETNROFELEM);
 
927
         lFreeList(&dlp);
 
928
      }
 
929
   }
 
930
 
 
931
   DEXIT;
 
932
   return dlp;
 
933
}
 
934
 
 
935
/****** cull/db/lPartialDescr() ***********************************************
 
936
*  NAME
 
937
*     lPartialDescr() -- Extracts some fields of a descriptor 
 
938
*
 
939
*  SYNOPSIS
 
940
*     int lPartialDescr(const lEnumeration *ep, const lDescr *sdp, 
 
941
*                       lDescr *ddp, int *indexp) 
 
942
*
 
943
*  FUNCTION
 
944
*     Extracts some fields of the source descriptor 'sdp' masked
 
945
*     by an enumeration 'ep' of needed fields 
 
946
*
 
947
*  INPUTS
 
948
*     const lEnumeration *ep - mask 
 
949
*     const lDescr *sdp      - source 
 
950
*     lDescr *ddp            - destination 
 
951
*     int *indexp            - 
 
952
*
 
953
*  RESULT
 
954
*     int - error state
 
955
*         0 - OK
 
956
*        -1 - Error 
 
957
*******************************************************************************/
 
958
int lPartialDescr(const lEnumeration *ep, const lDescr *sdp, lDescr *ddp,
 
959
                  int *indexp) 
 
960
{
 
961
   int i;
 
962
 
 
963
   DENTER(CULL_LAYER, "lPartialDescr");
 
964
 
 
965
   if (!ep) {
 
966
      LERROR(LEELEMNULL);
 
967
      DEXIT;
 
968
      return -1;
 
969
   }
 
970
   if (!sdp || !ddp) {
 
971
      LERROR(LEDESCRNULL);
 
972
      DEXIT;
 
973
      return -1;
 
974
   }
 
975
   if (!indexp) {
 
976
      LERROR(LENULLARGS);
 
977
      DEXIT;
 
978
      return -1;
 
979
   }
 
980
 
 
981
   switch (ep[0].pos) {
 
982
   case WHAT_NONE:
 
983
      DEXIT;
 
984
      return 0;
 
985
   case WHAT_ALL:
 
986
      for (i = 0; sdp[i].mt != lEndT; i++) {
 
987
         ddp[*indexp].mt = sdp[i].mt;
 
988
         ddp[*indexp].nm = sdp[i].nm;
 
989
         ddp[*indexp].ht = NULL;
 
990
 
 
991
         (*indexp)++;
 
992
      }
 
993
      break;
 
994
   default:
 
995
      {
 
996
         int maxpos = 0;
 
997
         maxpos = lCountDescr(sdp);
 
998
 
 
999
         /* copy and check descr */
 
1000
         for (i = 0; ep[i].mt != lEndT; i++) {
 
1001
            if (mt_get_type(ep[i].mt) == mt_get_type(sdp[ep[i].pos].mt) &&
 
1002
                ep[i].nm == sdp[ep[i].pos].nm) {
 
1003
 
 
1004
               if (ep[i].pos > maxpos || ep[i].pos < 0) {
 
1005
                  LERROR(LEENUMDESCR);
 
1006
                  DEXIT;
 
1007
                  return -1;
 
1008
               }
 
1009
               ddp[*indexp].mt = sdp[ep[i].pos].mt;
 
1010
               ddp[*indexp].nm = sdp[ep[i].pos].nm;
 
1011
               ddp[*indexp].ht = NULL;
 
1012
    
 
1013
               (*indexp)++;
 
1014
            } else {
 
1015
               LERROR(LEENUMDESCR);
 
1016
               DEXIT;
 
1017
               return -1;
 
1018
            }
 
1019
         }
 
1020
      }
 
1021
   }
 
1022
   /* copy end mark */
 
1023
   ddp[*indexp].mt = lEndT;
 
1024
   ddp[*indexp].nm = NoName;
 
1025
   ddp[*indexp].ht = NULL;
 
1026
 
 
1027
   /* 
 
1028
      We don't do (*indexp)++ in order to end up correctly if
 
1029
      nothing follows and to overwrite at the end position if
 
1030
      we concatenate two descriptors
 
1031
    */
 
1032
 
 
1033
   DEXIT;
 
1034
   return 0;
 
1035
}
 
1036
 
 
1037
/****** cull/db/lJoinDescr() **************************************************
 
1038
*  NAME
 
1039
*     lJoinDescr() -- Builds new descriptor using two others 
 
1040
*
 
1041
*  SYNOPSIS
 
1042
*     lDescr* lJoinDescr(const lDescr *sdp0, 
 
1043
*                        const lDescr *sdp1, 
 
1044
*                        const lEnumeration *ep0, 
 
1045
*                        const lEnumeration *ep1) 
 
1046
*
 
1047
*  FUNCTION
 
1048
*     Bilds from two given descriptors 'sdp0' and 'sdp1' a new
 
1049
*     descriptor masked by the enumerations 'ep0' and 'ep1'. 
 
1050
*
 
1051
*  INPUTS
 
1052
*     const lDescr *sdp0      - first descriptor 
 
1053
*     const lDescr *sdp1      - second descriptor 
 
1054
*     const lEnumeration *ep0 - first mask 
 
1055
*     const lEnumeration *ep1 - second mask 
 
1056
*
 
1057
*  RESULT
 
1058
*     lDescr* - new descriptor
 
1059
******************************************************************************/
 
1060
lDescr *lJoinDescr(const lDescr *sdp0, const lDescr *sdp1, 
 
1061
                   const lEnumeration *ep0, const lEnumeration *ep1) 
 
1062
{
 
1063
   int n, m, index;
 
1064
   lDescr *ddp;
 
1065
 
 
1066
   DENTER(CULL_LAYER, "lJoinDescr");
 
1067
 
 
1068
   if (!sdp0 || !sdp1) {
 
1069
      LERROR(LEDESCRNULL);
 
1070
      DEXIT;
 
1071
      return NULL;
 
1072
   }
 
1073
 
 
1074
   if (!ep0 || !ep1) {
 
1075
      LERROR(LEELEMNULL);
 
1076
      DEXIT;
 
1077
      return NULL;
 
1078
   }
 
1079
 
 
1080
   /* compute size of new descr */
 
1081
   n = lCountWhat(ep0, sdp0);
 
1082
   m = lCountWhat(ep1, sdp1);
 
1083
 
 
1084
   if (n == -1 || m == -1) {
 
1085
      LERROR(LECOUNTWHAT);
 
1086
      DEXIT;
 
1087
      return NULL;
 
1088
   }
 
1089
 
 
1090
   /* There is WHAT_NONE specified in both lEnumeration ptr's */
 
1091
   if (!n && !m) {
 
1092
      LERROR(LEENUMBOTHNONE);
 
1093
      DEXIT;
 
1094
      return NULL;
 
1095
   }
 
1096
 
 
1097
   if (!(ddp = (lDescr *) malloc(sizeof(lDescr) * (n + m + 1)))) {
 
1098
      LERROR(LEMALLOC);
 
1099
      DEXIT;
 
1100
      return NULL;
 
1101
   }
 
1102
   /* INITIALIZE THE INDEX IF YOU BUILD A NEW DESCRIPTOR */
 
1103
   index = 0;
 
1104
   if (lPartialDescr(ep0, sdp0, ddp, &index) < 0) {
 
1105
      LERROR(LEPARTIALDESCR);
 
1106
      free(ddp);
 
1107
      DEXIT;
 
1108
      return NULL;
 
1109
   }
 
1110
   /* This one is appended */
 
1111
   if (lPartialDescr(ep1, sdp1, ddp, &index) < 0) {
 
1112
      LERROR(LEPARTIALDESCR);
 
1113
      free(ddp);
 
1114
      DEXIT;
 
1115
      return NULL;
 
1116
   }
 
1117
 
 
1118
   DEXIT;
 
1119
   return ddp;
 
1120
}
 
1121
 
 
1122
lDescr *lGetReducedDescr(const lDescr *type, const lEnumeration *what) {
 
1123
 
 
1124
   lDescr *new = NULL;
 
1125
   int index = 0;
 
1126
   int n = 0;
 
1127
   DENTER(CULL_LAYER, "lGetReducedDescr");
 
1128
  
 
1129
   if ((n = lCountWhat(what, type)) <= 0) {
 
1130
      DEXIT;
 
1131
      return NULL;
 
1132
   }
 
1133
   
 
1134
   if (!(new= (lDescr *) malloc(sizeof(lDescr) * (n + 1)))) {
 
1135
      DEXIT;
 
1136
      return NULL;
 
1137
   }
 
1138
   if (lPartialDescr(what, type, new, &index) != 0){
 
1139
      FREE(new);
 
1140
      DEXIT;
 
1141
      return NULL;      
 
1142
   }
 
1143
  
 
1144
   DEXIT;
 
1145
   return new;
 
1146
}
 
1147
 
 
1148
/****** cull/db/lString2List() ************************************************
 
1149
*  NAME
 
1150
*     lString2List() -- Convert char* string into CULL list 
 
1151
*
 
1152
*  SYNOPSIS
 
1153
*     int lString2List(const char *s, lList **lpp, const lDescr *dp, 
 
1154
*                      int nm, const char *delimitor); 
 
1155
*
 
1156
*  FUNCTION
 
1157
*     Parses separated strings and adds them into the cull list *lpp
 
1158
*     The string is a unique key for the list and resides at field 'nm'
 
1159
*     If 'deleminator' is NULL than isspace() is used. 
 
1160
*
 
1161
*  INPUTS
 
1162
*     const char *s         - String to parse   
 
1163
*     lList **lpp           - reference to lList*      
 
1164
*     const lDescr *dp      - list Type     
 
1165
*     int nm                - list field       
 
1166
*     const char *delimitor - string delimitor        
 
1167
*
 
1168
*  RESULT
 
1169
*     int - error state
 
1170
*         1 - OK
 
1171
*         0 - On error
 
1172
******************************************************************************/
 
1173
int lString2List(const char *s, lList **lpp, const lDescr *dp, int nm, 
 
1174
                 const char *dlmt) 
 
1175
{
 
1176
   int pos;
 
1177
   int dataType;
 
1178
   struct saved_vars_s *context = NULL;
 
1179
 
 
1180
   DENTER(TOP_LAYER, "lString2List");
 
1181
 
 
1182
   if (!s) {
 
1183
      DEXIT;
 
1184
      return 1;
 
1185
   }
 
1186
 
 
1187
   pos = lGetPosInDescr(dp, nm);
 
1188
   dataType = lGetPosType(dp, pos);
 
1189
   switch (dataType) {
 
1190
      case lStringT:
 
1191
         DPRINTF(("lString2List: got lStringT data type\n"));
 
1192
         for (s = sge_strtok_r(s, dlmt, &context); s; s = sge_strtok_r(NULL, dlmt, &context)) {
 
1193
            if (lGetElemStr(*lpp, nm, s)) {
 
1194
               /* silently ignore multiple occurencies */
 
1195
               continue;
 
1196
            }
 
1197
            if (!lAddElemStr(lpp, nm, s, dp)) {
 
1198
               sge_free_saved_vars(context);
 
1199
               lFreeList(lpp);
 
1200
               DEXIT;
 
1201
               return 1;
 
1202
            }
 
1203
         }
 
1204
 
 
1205
         break;
 
1206
      case lHostT:
 
1207
         DPRINTF(("lString2List: got lHostT data type\n"));
 
1208
         for (s = sge_strtok_r(s, dlmt, &context); s; s = sge_strtok_r(NULL, dlmt, &context)) {
 
1209
            if (lGetElemHost(*lpp, nm, s)) {
 
1210
               /* silently ignore multiple occurencies */
 
1211
               continue;
 
1212
            }
 
1213
            if (!lAddElemHost(lpp, nm, s, dp)) {
 
1214
               sge_free_saved_vars(context);
 
1215
               lFreeList(lpp);
 
1216
               DEXIT;
 
1217
               return 1;
 
1218
            }
 
1219
         }
 
1220
 
 
1221
         break;
 
1222
      default:
 
1223
         DPRINTF(("lString2List: unexpected data type\n"));
 
1224
         break;
 
1225
   }
 
1226
 
 
1227
   if (context)   
 
1228
      sge_free_saved_vars(context);
 
1229
 
 
1230
   DEXIT;
 
1231
   return 0;
 
1232
}
 
1233
 
 
1234
/****** cull/db/lString2ListNone() ********************************************
 
1235
*  NAME
 
1236
*     lString2ListNone() -- 
 
1237
*
 
1238
*  SYNOPSIS
 
1239
*     int lString2ListNone(const char *s, lList **lpp, const lDescr *dp, 
 
1240
*                          int nm, const char *dlmt) 
 
1241
*
 
1242
*  FUNCTION
 
1243
*
 
1244
*  INPUTS
 
1245
*     const char *s    - ??? 
 
1246
*     lList **lpp      - ??? 
 
1247
*     const lDescr *dp - ??? 
 
1248
*     int nm           - ??? 
 
1249
*     const char *dlmt - ??? 
 
1250
*
 
1251
*  RESULT
 
1252
*     int - error state 
 
1253
*         0 - OK
 
1254
*  EXAMPLE
 
1255
*
 
1256
*  NOTES
 
1257
*
 
1258
*  BUGS
 
1259
*
 
1260
*  SEE ALSO
 
1261
******************************************************************************/
 
1262
int lString2ListNone(const char *s, lList **lpp, const lDescr *dp,
 
1263
                     int nm, const char *dlmt) 
 
1264
{
 
1265
   int pos;
 
1266
   int dataType;
 
1267
   if (lString2List(s, lpp, dp, nm, dlmt))
 
1268
      return 1;
 
1269
 
 
1270
 
 
1271
   pos = lGetPosInDescr(dp, nm);
 
1272
   dataType = lGetPosType(dp, pos);
 
1273
   switch(dataType) {
 
1274
      case lStringT:
 
1275
         DPRINTF(("lString2ListNone: got lStringT data type\n"));
 
1276
         if (lGetNumberOfElem(*lpp) > 1 && lGetElemCaseStr(*lpp, nm, "none")) {
 
1277
            lFreeList(lpp);
 
1278
            return 1;
 
1279
         }
 
1280
 
 
1281
         if (lGetNumberOfElem(*lpp) == 1 && lGetElemCaseStr(*lpp, nm, "none"))
 
1282
            lFreeList(lpp);
 
1283
         break;
 
1284
      case lHostT:
 
1285
         DPRINTF(("lString2ListNone: got lHostT data type\n"));
 
1286
         if (lGetNumberOfElem(*lpp) > 1 && lGetElemHost(*lpp, nm, "none")) {
 
1287
            lFreeList(lpp);
 
1288
            return 1;
 
1289
         }
 
1290
 
 
1291
         if (lGetNumberOfElem(*lpp) == 1 && lGetElemHost(*lpp, nm, "none"))
 
1292
            lFreeList(lpp);
 
1293
         break;
 
1294
 
 
1295
      default:
 
1296
         DPRINTF(("lString2ListNone: unexpected data type\n"));
 
1297
         break;
 
1298
   }
 
1299
 
 
1300
   return 0;
 
1301
}
 
1302
 
 
1303
/****** cull/db/lDiffListStr() ************************************************
 
1304
*  NAME
 
1305
*     lDiffListStr() -- Remove elements with the same string
 
1306
*
 
1307
*  SYNOPSIS
 
1308
*     int lDiffListStr(int nm, lList **lpp1, lList **lpp2) 
 
1309
*
 
1310
*  FUNCTION
 
1311
*     Remove elements in both lists with the same string key in 
 
1312
*     field 'nm'.
 
1313
*
 
1314
*  INPUTS
 
1315
*     int nm       - field name id 
 
1316
*     lList **lpp1 - first list 
 
1317
*     lList **lpp2 - second list 
 
1318
*
 
1319
*  RESULT
 
1320
*     int - error status
 
1321
*         0 - OK
 
1322
*        -1 - Error
 
1323
******************************************************************************/
 
1324
int lDiffListStr(int nm, lList **lpp1, lList **lpp2) 
 
1325
{
 
1326
   const char *key;
 
1327
   lListElem *ep, *to_check;
 
1328
 
 
1329
   DENTER(CULL_LAYER, "lDiffListStr");
 
1330
 
 
1331
   if (!lpp1 || !lpp2) {
 
1332
      DRETURN(-1);
 
1333
   }
 
1334
 
 
1335
   if (!*lpp1 || !*lpp2) {
 
1336
      DRETURN(0);
 
1337
   }
 
1338
 
 
1339
   ep = lFirst(*lpp1);
 
1340
   while (ep) {
 
1341
      to_check = ep;
 
1342
      key = lGetString(to_check, nm);
 
1343
 
 
1344
      ep = lNext(ep);           /* point to next element before del */
 
1345
 
 
1346
      if (lGetElemStr(*lpp2, nm, key) != NULL) {
 
1347
         lDelElemStr(lpp2, nm, key);
 
1348
         lDelElemStr(lpp1, nm, key);
 
1349
      }
 
1350
   }
 
1351
 
 
1352
   DRETURN(0);
 
1353
}