1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
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
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.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
36
/* do not compile in monitoring code */
37
#ifndef NO_SGE_COMPILE_DEBUG
38
#define NO_SGE_COMPILE_DEBUG
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"
53
static lListElem *lJoinCopyElem(const lDescr *dp,
54
const lListElem *sep0,
55
const lEnumeration *ep0,
56
const lListElem *sep1,
57
const lEnumeration *ep1);
59
/****** cull/db/lJoinCopyElem() ***********************************************
61
* lJoinCopyElem() -- Combine two elements
64
* static lListElem* lJoinCopyElem(const lDescr *dp,
65
* const lListElem *src0,
66
* const lEnumeration *enp0,
67
* const lListElem *src1,
68
* const lEnumeration *enp1)
71
* Returns a combined element with descriptor 'dp'. Uses 'src0'
72
* with mask 'enp0' and 'src1' with mask 'enp1' as source.
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
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)
93
DENTER(CULL_LAYER, "lJoinCopyElem");
101
if (!(dst = lCreateElem(dp))) {
102
LERROR(LECREATEELEM);
108
if (lCopyElemPartialPack(dst, &i, src0, enp0, true, NULL) == -1) {
110
LERROR(LECOPYELEMPART);
114
if (lCopyElemPartialPack(dst, &i, src1, enp1, true, NULL) == -1) {
116
LERROR(LECOPYELEMPART);
125
/****** cull/db/lJoinSublist() ************************************************
127
* lJoinSublist() -- Join a list with one of its sublists
130
* lList* lJoinSublist(const char *name,
133
* const lCondition *cp0,
134
* const lEnumeration *enp0,
135
* const lDescr *sldp,
136
* const lCondition *cp1,
137
* const lEnumeration *enp1)
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'
146
* const char *name - new list name
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'
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)
163
lList *dlp, *tlp, *joinedlist, *sublist;
169
DENTER(CULL_LAYER, "lJoinSublist");
171
/* check different pointers */
172
if (!name || !lp || !enp0 || !sldp || !enp1) {
178
/* make sure that nm0 is a sublist field of lp */
179
if (!(tdp = lGetListDescr(lp))) {
184
if ((pos = lGetPosInDescr(tdp, nm0)) < 0) {
190
if (mt_get_type(tdp[pos].mt) != lListT) {
196
/* is nm0 enumerated in enp0 ? */
197
if (enp0[0].pos == WHAT_ALL) {
198
LERROR(LEFALSEFIELD);
202
for (i = 0; enp0[i].nm != NoName; i++)
203
if (enp0[i].nm == nm0) {
204
LERROR(LEFALSEFIELD);
209
/* create destination list */
210
if (!(dp = lJoinDescr(lGetListDescr(lp), sldp, enp0, enp1))) {
215
if (!(dlp = lCreateList(name, dp))) {
217
LERROR(LECREATELIST);
221
/* free dp it has been copied in lCreateList */
224
/* create a temporary list to be used by lJoin */
225
if (!(tlp = lCreateList("lJoinSublist: tlp", lGetListDescr(lp)))) {
227
LERROR(LECREATELIST);
232
for_each_where(ep, lp, cp0) {
233
/* is there a sublist for the join */
234
if ((sublist = lGetList(ep, nm0)) != NULL) {
236
/* put each element in the tlp to be used by lJoin */
237
if (lAppendElem(tlp, lCopyElem(ep)) == -1) {
240
LERROR(LEAPPENDELEM);
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);
257
/* joinedlist is freed in lAddList */
258
if (joinedlist && lAddList(dlp, &joinedlist) == -1) {
266
/* dechain the only element from tlp and free it (copy) */
267
lRemoveElem(tlp, &(tlp->first));
270
/* temporary list has to be freed */
273
/* RETURN AN EMPTY LIST OR NULL THAT'S THE QUESTION */
275
if (lGetNumberOfElem(dlp) == 0) {
283
/****** cull/db/lJoin() *******************************************************
285
* lJoin() -- Joins two lists together
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)
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.
302
* const char *name - name of new list
304
* const lList *lp0 - first list
305
* const lCondition *cp0 - selects rows of first list
306
* const lEnumeration *enp0 - selects column of first list
308
* const lList *lp1 - second list
309
* const lCondition *cp1 - selects rows of second list
310
* const lEnumeration *enp1 - selects column of seconf list
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)
319
lListElem *ep0, *ep1;
323
int lp0_pos = 0, lp1_pos = 0;
327
DENTER(CULL_LAYER, "lJoin");
329
if (!lp0 || !lp1 || !name || !enp0 || !enp1) {
336
if ((lp0_pos = lGetPosInDescr(lGetListDescr(lp0), nm0)) < 0) {
341
if ((lp1_pos = lGetPosInDescr(lGetListDescr(lp1), nm1)) < 0) {
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) {
355
/* the real join ?! */
356
if (!(dp = lJoinDescr(lGetListDescr(lp0), lGetListDescr(lp1), enp0, enp1))) {
361
if (!(dlp = lCreateList(name, dp))) {
362
LERROR(LECREATELIST);
367
/* free dp it has been copied by lCreateList */
370
for (i = 0, ep0 = lp0->first; i < lp0->nelem; i++, ep0 = ep0->next) {
371
if (!lCompare(ep0, cp0))
373
for (j = 0, ep1 = lp1->first; j < lp1->nelem; j++, ep1 = ep1->next) {
374
if (!lCompare(ep1, cp1))
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)) {
380
needed = (ep0->cont[lp0_pos].i == ep1->cont[lp1_pos].i);
383
needed = (ep0->cont[lp0_pos].ul == ep1->cont[lp1_pos].ul);
386
needed = !strcmp(ep0->cont[lp0_pos].str, ep1->cont[lp1_pos].str);
389
needed = !strcmp(ep0->cont[lp0_pos].str, ep1->cont[lp1_pos].str);
392
needed = (ep0->cont[lp0_pos].l == ep1->cont[lp1_pos].l);
395
needed = (ep0->cont[lp0_pos].fl == ep1->cont[lp1_pos].fl);
398
needed = (ep0->cont[lp0_pos].db == ep1->cont[lp1_pos].db);
401
needed = (ep0->cont[lp0_pos].c == ep1->cont[lp1_pos].c);
404
needed = (ep0->cont[lp0_pos].b == ep1->cont[lp1_pos].b);
407
needed = (ep0->cont[lp0_pos].ref == ep1->cont[lp1_pos].ref);
410
unknownType("lJoin");
417
if (!(ep = lJoinCopyElem(dlp->descr, ep0, enp0, ep1, enp1))) {
418
LERROR(LEJOINCOPYELEM);
424
if (lAppendElem(dlp, ep) == -1) {
425
LERROR(LEAPPENDELEM);
434
/* RETURN AN EMPTY LIST OR NULL THAT'S THE QUESTION */
436
if (lGetNumberOfElem(dlp) == 0) {
444
/****** cull/db/lSplit() ******************************************************
446
* lSplit() -- Splits a list into two list
449
* int lSplit(lList **slp, lList **ulp, const char *ulp_name,
450
* const lCondition *cp)
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'
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'
467
******************************************************************************/
468
int lSplit(lList **slp, lList **ulp, const char *ulp_name,
469
const lCondition *cp)
472
lListElem *ep, *next;
473
int has_been_allocated = 0;
475
DENTER(TOP_LAYER, "lSplit");
478
iterate through the source list call lCompare and chain all elems
479
that don't fullfill the condition into a new list.
486
for (ep = lFirst(*slp); ep; ep = next) {
487
next = ep->next; /* this is important, cause the elem is dechained */
489
if (!lCompare(ep, cp)) {
491
*ulp = lCreateList(ulp_name ? ulp_name : "ulp", (*slp)->descr);
496
has_been_allocated = 1;
499
ep = lDechainElem(*slp, ep);
500
lAppendElem(*ulp, ep);
502
lRemoveElem(*slp, &ep);
507
/* if no elements remain, free the list and return NULL */
508
if (*slp && lGetNumberOfElem(*slp) == 0) {
511
if (has_been_allocated && *ulp && lGetNumberOfElem(*ulp) == 0) {
519
/****** cull/db/lSelectDestroy() **********************************************
521
* lSelectDestroy() -- Removes the not needed list elements
524
* lList* lSelectDestroy(lList *slp, const lCondition *cp)
527
* Removes the not needed list elements from the list 'slp' NOT
528
* fulfilling the condition 'cp'
531
* lList *slp - source list pointer
532
* const lCondition *cp - selects rows
535
* lList* - List with the remaining elements
536
******************************************************************************/
537
lList *lSelectDestroy(lList *slp, const lCondition *cp)
540
DENTER(CULL_LAYER, "lSelectDestroy");
542
if (lSplit(&slp, NULL, NULL, cp)) {
551
/****** cull/db/lSelectElemPack() *********************************************
553
* lSelectElemPack() -- Extracts some elements fulfilling a condition
557
* lSelectElemPack(const lListElem *slp, const lCondition *cp,
558
* const lEnumeration *enp, bool isHash,
559
* sge_pack_buffer *pb)
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'.
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
574
* lListElem* - list containing the extracted elements
575
******************************************************************************/
577
lSelectElemPack(const lListElem *slp, const lCondition *cp,
578
const lEnumeration *enp, bool isHash, sge_pack_buffer *pb)
580
lListElem *new = NULL;
582
DENTER(CULL_LAYER, "lSelectElemPack");
591
u_long32 elements = 0;
593
/* create new lList with partial descriptor */
594
if ((n = lCountWhat(enp, slp->descr)) <= 0) {
599
if (!(dp = (lDescr *) malloc(sizeof(lDescr) * (n + 1)))) {
604
/* INITIALIZE THE INDEX IF YOU BUILD A NEW DESCRIPTOR */
605
if (lPartialDescr(enp, slp->descr, dp, &index) < 0) {
606
LERROR(LEPARTIALDESCR);
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);
617
/* no enumeration => make a copy of element */
618
new = lCopyElemHash(slp, isHash);
624
/****** cull/db/lSelectElemDPack() ********************************************
626
* lSelectElemDPack() -- Extracts some elements fulfilling a condition
630
* lSelectElemDPack(const lListelem *slp, const lCondition *cp,
631
* const lEnumeration *enp, bool isHash,
632
* sge_pack_buffer *pb)
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
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)
650
* lListElem* - list containing the extracted elements
651
******************************************************************************/
653
lSelectElemDPack(const lListElem *slp, const lCondition *cp, const lDescr *dp,
654
const lEnumeration *enp, bool isHash, sge_pack_buffer *pb,
657
lListElem *new = NULL;
660
DENTER(CULL_LAYER, "lSelectElemDPack");
661
if (!slp || (!dp && !pb)) {
666
* iterate through the source list call lCompare and add
667
* depending on result of lCompare
669
if (lCompare(slp, cp)) {
671
if (!(new = lCreateElem(dp))) {
676
if (lCopyElemPartialPack(new, &index, slp, enp, isHash, pb)) {
680
if (elements != NULL) {
684
lCopyElemPartialPack(NULL, &index, slp, enp, isHash, pb);
692
/****** cull/db/lSelect() *****************************************************
694
* lSelect() -- Extracts some elements fulfilling a condition
697
* lList* lSelect(const char *name, const lList *slp,
698
* const lCondition *cp, const lEnumeration *enp)
701
* Creates a new list from the list 'slp' extracting the elements
702
* fulfilling the condition 'cp'.
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
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);
718
/****** cull/db/lSelectHashPack() *********************************************
720
* lSelectHashPack() -- Extracts some elements fulfilling a condition
724
* lSelectHashPack(const char *name, const lList *slp,
725
* const lCondition *cp, const lEnumeration *enp,
726
* bool isHash, sge_pack_buffer *pb)
729
* Creates a new list from the list 'slp' extracting the elements
730
* fulfilling the condition 'cp' or fills the packbuffer if pb is
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
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)
750
DENTER(CULL_LAYER, "lSelectHashPack");
751
if (slp == NULL && pb == NULL) {
761
/* create new lList with partial descriptor */
762
n = lCountWhat(enp, slp->descr);
769
dp = malloc(sizeof(lDescr) * (n + 1));
776
/* INITIALIZE THE INDEX IF YOU BUILD A NEW DESCRIPTOR */
778
if (lPartialDescr(enp, slp->descr, dp, &index) < 0) {
779
LERROR(LEPARTIALDESCR);
784
ret = lSelectDPack(name, slp, cp, dp, enp, isHash, NULL, NULL);
786
/* free the descriptor, it has been copied by lCreateList */
787
cull_hash_free_descr(dp);
790
u_long32 number_of_packed_elements = 0;
793
const char *pack_name = "";
798
} else if (slp != NULL) {
799
pack_name = slp->listname;
802
local_ret = cull_pack_list_summary(pb, slp, enp, pack_name, &offset, &used);
803
if (local_ret != PACK_SUCCESS) {
809
lSelectDPack(name, slp, cp, NULL, enp, isHash, pb,
810
&number_of_packed_elements);
813
* change number of elements contained in the packbuffer
815
if (slp != NULL && pb != NULL) {
816
char *old_cur_ptr = NULL;
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;
824
local_ret = repackint(pb, number_of_packed_elements);
825
if(local_ret != PACK_SUCCESS) {
830
pb->cur_ptr = old_cur_ptr;
831
pb->bytes_used = old_used;
836
ret = lCopyListHash(slp->listname, slp, isHash);
838
cull_pack_list(pb, slp);
845
/****** cull_db/lSelectDPack() ************************************************
847
* lSelectDPack() -- Extracts some elements fulfilling a condition
850
* lList* lSelectDPack(const char *name, const lList *slp,
851
* const lCondition *cp, const lDescr *dp,
852
* bool isHash, sge_pack_buffer *pb)
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.
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)
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)
880
lList *dlp = (lList *) NULL;
881
const lDescr *descr = NULL;
883
DENTER(CULL_LAYER, "lSelectDPack");
885
if (!slp || (!dp && !pb)) {
891
if (!(dlp = lCreateListHash(name, dp, false))) {
892
LERROR(LECREATELIST);
896
dlp->changed = slp->changed;
901
iterate through the source list call lCompare and add
902
depending on result of lCompare
904
for (ep = slp->first; ep; ep = ep->next) {
905
new = lSelectElemDPack(ep, cp, descr, enp, isHash, pb, elements);
907
if (lAppendElem(dlp, new) == -1) {
908
LERROR(LEAPPENDELEM);
917
if (pb == NULL && isHash) {
918
/* now create the hash tables */
919
cull_hash_create_hashtables(dlp);
922
* This is a question of philosophy.
923
* To return an empty list or not to return.
925
if (lGetNumberOfElem(dlp) == 0) {
926
LERROR(LEGETNROFELEM);
935
/****** cull/db/lPartialDescr() ***********************************************
937
* lPartialDescr() -- Extracts some fields of a descriptor
940
* int lPartialDescr(const lEnumeration *ep, const lDescr *sdp,
941
* lDescr *ddp, int *indexp)
944
* Extracts some fields of the source descriptor 'sdp' masked
945
* by an enumeration 'ep' of needed fields
948
* const lEnumeration *ep - mask
949
* const lDescr *sdp - source
950
* lDescr *ddp - destination
957
*******************************************************************************/
958
int lPartialDescr(const lEnumeration *ep, const lDescr *sdp, lDescr *ddp,
963
DENTER(CULL_LAYER, "lPartialDescr");
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;
997
maxpos = lCountDescr(sdp);
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) {
1004
if (ep[i].pos > maxpos || ep[i].pos < 0) {
1005
LERROR(LEENUMDESCR);
1009
ddp[*indexp].mt = sdp[ep[i].pos].mt;
1010
ddp[*indexp].nm = sdp[ep[i].pos].nm;
1011
ddp[*indexp].ht = NULL;
1015
LERROR(LEENUMDESCR);
1023
ddp[*indexp].mt = lEndT;
1024
ddp[*indexp].nm = NoName;
1025
ddp[*indexp].ht = NULL;
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
1037
/****** cull/db/lJoinDescr() **************************************************
1039
* lJoinDescr() -- Builds new descriptor using two others
1042
* lDescr* lJoinDescr(const lDescr *sdp0,
1043
* const lDescr *sdp1,
1044
* const lEnumeration *ep0,
1045
* const lEnumeration *ep1)
1048
* Bilds from two given descriptors 'sdp0' and 'sdp1' a new
1049
* descriptor masked by the enumerations 'ep0' and 'ep1'.
1052
* const lDescr *sdp0 - first descriptor
1053
* const lDescr *sdp1 - second descriptor
1054
* const lEnumeration *ep0 - first mask
1055
* const lEnumeration *ep1 - second mask
1058
* lDescr* - new descriptor
1059
******************************************************************************/
1060
lDescr *lJoinDescr(const lDescr *sdp0, const lDescr *sdp1,
1061
const lEnumeration *ep0, const lEnumeration *ep1)
1066
DENTER(CULL_LAYER, "lJoinDescr");
1068
if (!sdp0 || !sdp1) {
1069
LERROR(LEDESCRNULL);
1080
/* compute size of new descr */
1081
n = lCountWhat(ep0, sdp0);
1082
m = lCountWhat(ep1, sdp1);
1084
if (n == -1 || m == -1) {
1085
LERROR(LECOUNTWHAT);
1090
/* There is WHAT_NONE specified in both lEnumeration ptr's */
1092
LERROR(LEENUMBOTHNONE);
1097
if (!(ddp = (lDescr *) malloc(sizeof(lDescr) * (n + m + 1)))) {
1102
/* INITIALIZE THE INDEX IF YOU BUILD A NEW DESCRIPTOR */
1104
if (lPartialDescr(ep0, sdp0, ddp, &index) < 0) {
1105
LERROR(LEPARTIALDESCR);
1110
/* This one is appended */
1111
if (lPartialDescr(ep1, sdp1, ddp, &index) < 0) {
1112
LERROR(LEPARTIALDESCR);
1122
lDescr *lGetReducedDescr(const lDescr *type, const lEnumeration *what) {
1127
DENTER(CULL_LAYER, "lGetReducedDescr");
1129
if ((n = lCountWhat(what, type)) <= 0) {
1134
if (!(new= (lDescr *) malloc(sizeof(lDescr) * (n + 1)))) {
1138
if (lPartialDescr(what, type, new, &index) != 0){
1148
/****** cull/db/lString2List() ************************************************
1150
* lString2List() -- Convert char* string into CULL list
1153
* int lString2List(const char *s, lList **lpp, const lDescr *dp,
1154
* int nm, const char *delimitor);
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.
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
1172
******************************************************************************/
1173
int lString2List(const char *s, lList **lpp, const lDescr *dp, int nm,
1178
struct saved_vars_s *context = NULL;
1180
DENTER(TOP_LAYER, "lString2List");
1187
pos = lGetPosInDescr(dp, nm);
1188
dataType = lGetPosType(dp, pos);
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 */
1197
if (!lAddElemStr(lpp, nm, s, dp)) {
1198
sge_free_saved_vars(context);
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 */
1213
if (!lAddElemHost(lpp, nm, s, dp)) {
1214
sge_free_saved_vars(context);
1223
DPRINTF(("lString2List: unexpected data type\n"));
1228
sge_free_saved_vars(context);
1234
/****** cull/db/lString2ListNone() ********************************************
1236
* lString2ListNone() --
1239
* int lString2ListNone(const char *s, lList **lpp, const lDescr *dp,
1240
* int nm, const char *dlmt)
1245
* const char *s - ???
1247
* const lDescr *dp - ???
1249
* const char *dlmt - ???
1261
******************************************************************************/
1262
int lString2ListNone(const char *s, lList **lpp, const lDescr *dp,
1263
int nm, const char *dlmt)
1267
if (lString2List(s, lpp, dp, nm, dlmt))
1271
pos = lGetPosInDescr(dp, nm);
1272
dataType = lGetPosType(dp, pos);
1275
DPRINTF(("lString2ListNone: got lStringT data type\n"));
1276
if (lGetNumberOfElem(*lpp) > 1 && lGetElemCaseStr(*lpp, nm, "none")) {
1281
if (lGetNumberOfElem(*lpp) == 1 && lGetElemCaseStr(*lpp, nm, "none"))
1285
DPRINTF(("lString2ListNone: got lHostT data type\n"));
1286
if (lGetNumberOfElem(*lpp) > 1 && lGetElemHost(*lpp, nm, "none")) {
1291
if (lGetNumberOfElem(*lpp) == 1 && lGetElemHost(*lpp, nm, "none"))
1296
DPRINTF(("lString2ListNone: unexpected data type\n"));
1303
/****** cull/db/lDiffListStr() ************************************************
1305
* lDiffListStr() -- Remove elements with the same string
1308
* int lDiffListStr(int nm, lList **lpp1, lList **lpp2)
1311
* Remove elements in both lists with the same string key in
1315
* int nm - field name id
1316
* lList **lpp1 - first list
1317
* lList **lpp2 - second list
1320
* int - error status
1323
******************************************************************************/
1324
int lDiffListStr(int nm, lList **lpp1, lList **lpp2)
1327
lListElem *ep, *to_check;
1329
DENTER(CULL_LAYER, "lDiffListStr");
1331
if (!lpp1 || !lpp2) {
1335
if (!*lpp1 || !*lpp2) {
1342
key = lGetString(to_check, nm);
1344
ep = lNext(ep); /* point to next element before del */
1346
if (lGetElemStr(*lpp2, nm, key) != NULL) {
1347
lDelElemStr(lpp2, nm, key);
1348
lDelElemStr(lpp1, nm, key);