valueset.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. /* valueset.c - routines for dealing with value sets */
  42. #include "slap.h"
  43. #include "slapi-private.h"
  44. /* <=========================== Berval Array ==========================> */
  45. /*
  46. * vals - The existing values.
  47. * addval - The value to add.
  48. * nvals - The number of existing values.
  49. * maxvals - The number of elements in the existing values array.
  50. */
  51. void
  52. bervalarray_add_berval_fast(
  53. struct berval ***vals,
  54. const struct berval *addval,
  55. int nvals,
  56. int *maxvals
  57. )
  58. {
  59. int need = nvals + 2;
  60. if(need>*maxvals)
  61. {
  62. if (*maxvals==0)
  63. {
  64. *maxvals = 2;
  65. }
  66. while ( *maxvals < need )
  67. {
  68. *maxvals *= 2;
  69. }
  70. if(*vals==NULL)
  71. {
  72. *vals = (struct berval **) slapi_ch_malloc( *maxvals * sizeof(struct berval *));
  73. }
  74. else
  75. {
  76. *vals = (struct berval **) slapi_ch_realloc( (char *) *vals, *maxvals * sizeof(struct berval *));
  77. }
  78. }
  79. (*vals)[nvals] = ber_bvdup( (struct berval *)addval );
  80. (*vals)[nvals+1] = NULL;
  81. }
  82. /* <=========================== Value Array ==========================> */
  83. /*
  84. * vals - The existing values.
  85. * addval - The value to add.
  86. * nvals - The number of existing values.
  87. * maxvals - The number of elements in the existing values array.
  88. */
  89. void
  90. valuearray_add_value_fast(Slapi_Value ***vals,
  91. Slapi_Value *addval,
  92. int nvals,
  93. int *maxvals,
  94. int exact, /* Don't create an array bigger than needed */
  95. int passin) /* The values are being passed in */
  96. {
  97. Slapi_Value *oneval[2];
  98. oneval[0]= addval;
  99. oneval[1]= NULL;
  100. valuearray_add_valuearray_fast(vals,oneval,nvals,1,maxvals,exact,passin);
  101. }
  102. void
  103. valuearray_add_valuearray_fast(Slapi_Value ***vals,
  104. Slapi_Value **addvals,
  105. int nvals,
  106. int naddvals,
  107. int *maxvals,
  108. int exact, /* Don't create an array bigger than needed */
  109. int passin) /* The values are being passed in */
  110. {
  111. int i, j;
  112. int allocate= 0;
  113. int need = nvals + naddvals + 1;
  114. if(exact)
  115. {
  116. /* Create an array exactly the right size. */
  117. if(need>*maxvals)
  118. {
  119. allocate= need;
  120. }
  121. }
  122. else
  123. {
  124. if (*maxvals==0) /* empty; create with 4 by default */
  125. {
  126. allocate= 4;
  127. }
  128. else if (need > *maxvals)
  129. {
  130. /* Exponentially expand the array */
  131. allocate= *maxvals;
  132. while ( allocate < need )
  133. {
  134. allocate *= 2;
  135. }
  136. }
  137. }
  138. if(allocate>0)
  139. {
  140. if(*vals==NULL)
  141. {
  142. *vals = (Slapi_Value **) slapi_ch_malloc( allocate * sizeof(Slapi_Value *));
  143. }
  144. else
  145. {
  146. *vals = (Slapi_Value **) slapi_ch_realloc( (char *) *vals, allocate * sizeof(Slapi_Value *));
  147. }
  148. *maxvals= allocate;
  149. }
  150. for ( i = 0, j = 0; i < naddvals; i++)
  151. {
  152. if ( addvals[i]!=NULL )
  153. {
  154. if(passin)
  155. {
  156. /* We consume the values */
  157. (*vals)[nvals + j] = addvals[i];
  158. }
  159. else
  160. {
  161. /* We copy the values */
  162. (*vals)[nvals + j] = slapi_value_dup(addvals[i]);
  163. }
  164. j++;
  165. }
  166. }
  167. (*vals)[nvals + j] = NULL;
  168. }
  169. void
  170. valuearray_add_value(Slapi_Value ***vals, const Slapi_Value *addval)
  171. {
  172. Slapi_Value *oneval[2];
  173. oneval[0]= (Slapi_Value*)addval;
  174. oneval[1]= NULL;
  175. valuearray_add_valuearray(vals,oneval,0);
  176. }
  177. void
  178. valuearray_add_valuearray(Slapi_Value ***vals, Slapi_Value **addvals, PRUint32 flags)
  179. {
  180. int valslen;
  181. int addvalslen;
  182. int maxvals;
  183. if(vals == NULL){
  184. return;
  185. }
  186. addvalslen= valuearray_count(addvals);
  187. if(*vals == NULL)
  188. {
  189. valslen= 0;
  190. maxvals= 0;
  191. }
  192. else
  193. {
  194. valslen= valuearray_count(*vals);
  195. maxvals= valslen+1;
  196. }
  197. valuearray_add_valuearray_fast(vals,addvals,valslen,addvalslen,&maxvals,1/*Exact*/,flags & SLAPI_VALUE_FLAG_PASSIN);
  198. }
  199. int
  200. valuearray_count( Slapi_Value **va)
  201. {
  202. int i=0;
  203. if(va!=NULL)
  204. {
  205. while(NULL != va[i]) i++;
  206. }
  207. return(i);
  208. }
  209. int
  210. valuearray_isempty( Slapi_Value **va)
  211. {
  212. return va==NULL || va[0]==NULL;
  213. }
  214. /*
  215. * JCM SLOW FUNCTION
  216. *
  217. * WARNING: Use only if you absolutley need to...
  218. * This function mostly exists to map from the old slapi berval
  219. * based interface to the new Slapi_Value based interfaces.
  220. */
  221. int
  222. valuearray_init_bervalarray(struct berval **bvals, Slapi_Value ***cvals)
  223. {
  224. int n;
  225. for(n=0; bvals != NULL && bvals[n] != NULL; n++);
  226. if(n==0)
  227. {
  228. *cvals = NULL;
  229. }
  230. else
  231. {
  232. int i;
  233. *cvals = (Slapi_Value **) slapi_ch_malloc((n + 1) * sizeof(Slapi_Value *));
  234. for(i=0;i<n;i++)
  235. {
  236. (*cvals)[i] = slapi_value_new_berval(bvals[i]);
  237. }
  238. (*cvals)[i] = NULL;
  239. }
  240. return n;
  241. }
  242. /*
  243. * JCM SLOW FUNCTION
  244. *
  245. * WARNING: Use only if you absolutley need to...
  246. * This function mostly exists to map from the old slapi berval
  247. * based interface to the new Slapi_Value based interfaces.
  248. */
  249. int
  250. valuearray_init_bervalarray_with_flags(struct berval **bvals, Slapi_Value ***cvals, unsigned long flags)
  251. {
  252. int n;
  253. for(n=0; bvals != NULL && bvals[n] != NULL; n++);
  254. if(n==0)
  255. {
  256. *cvals = NULL;
  257. }
  258. else
  259. {
  260. int i;
  261. *cvals = (Slapi_Value **) slapi_ch_malloc((n + 1) * sizeof(Slapi_Value *));
  262. for(i=0;i<n;i++)
  263. {
  264. (*cvals)[i] = slapi_value_new_berval(bvals[i]);
  265. slapi_value_set_flags((*cvals)[i], flags);
  266. }
  267. (*cvals)[i] = NULL;
  268. }
  269. return n;
  270. }
  271. /*
  272. * JCM SLOW FUNCTION
  273. *
  274. * Use only if you absolutley need to...
  275. * This function mostly exists to map from the old slapi berval
  276. * based interface to the new Slapi_Value based interfaces.
  277. */
  278. int
  279. valuearray_get_bervalarray(Slapi_Value **cvals,struct berval ***bvals)
  280. {
  281. int i,n;
  282. n= valuearray_count(cvals);
  283. if (0 == n)
  284. {
  285. *bvals = NULL;
  286. }
  287. else
  288. {
  289. *bvals = (struct berval **)slapi_ch_malloc((n + 1) * sizeof(struct berval *));
  290. for(i=0;i<n;i++)
  291. {
  292. (*bvals)[i] = ber_bvdup((struct berval *)slapi_value_get_berval(cvals[i]));
  293. }
  294. (*bvals)[i] = NULL;
  295. }
  296. return(0);
  297. }
  298. void
  299. valuearray_free_ext(Slapi_Value ***va, int idx)
  300. {
  301. if(va!=NULL && *va!=NULL)
  302. {
  303. for(; (*va)[idx]!=NULL; idx++)
  304. {
  305. slapi_value_free(&(*va)[idx]);
  306. }
  307. slapi_ch_free((void **)va);
  308. *va = NULL;
  309. }
  310. }
  311. void
  312. valuearray_free(Slapi_Value ***va)
  313. {
  314. valuearray_free_ext(va, 0);
  315. }
  316. int
  317. valuearray_next_value( Slapi_Value **va, int index, Slapi_Value **v)
  318. {
  319. int r= -1;
  320. if(va!=NULL && va[0]!=NULL)
  321. {
  322. r= index+1;
  323. *v= va[r];
  324. if(*v==NULL)
  325. {
  326. r= -1;
  327. }
  328. }
  329. else
  330. {
  331. *v= NULL;
  332. }
  333. return r;
  334. }
  335. int
  336. valuearray_first_value( Slapi_Value **va, Slapi_Value **v )
  337. {
  338. return valuearray_next_value( va, -1, v);
  339. }
  340. /*
  341. * Find the value and return an index number to it.
  342. */
  343. int
  344. valuearray_find(const Slapi_Attr *a, Slapi_Value **va, const Slapi_Value *v)
  345. {
  346. int i= 0;
  347. int found= -1;
  348. while(found==-1 && va!=NULL && va[i]!=NULL)
  349. {
  350. if(slapi_value_compare( a, v, va[i])==0)
  351. {
  352. found= i;
  353. }
  354. else
  355. {
  356. i++;
  357. }
  358. }
  359. return found;
  360. }
  361. /*
  362. * Shunt up the array to cover the value to remove.
  363. */
  364. void
  365. valuearray_remove_value_atindex(Slapi_Value **va, int index)
  366. {
  367. if(va!=NULL && va[0]!=NULL)
  368. {
  369. int k;
  370. for ( k = index + 1; va[k] != NULL; k++ )
  371. {
  372. va[k - 1] = va[k];
  373. }
  374. va[k - 1] = NULL;
  375. }
  376. }
  377. /*
  378. * Find the value in the array,
  379. * shunt up the array to cover it,
  380. * return a ptr to the value.
  381. * The caller is responsible for freeing the value.
  382. */
  383. Slapi_Value *
  384. valuearray_remove_value(const Slapi_Attr *a, Slapi_Value **va, const Slapi_Value *v)
  385. {
  386. Slapi_Value *r= NULL;
  387. int i= 0;
  388. i= valuearray_find(a, va, v);
  389. if(i!=-1)
  390. {
  391. r= va[i];
  392. valuearray_remove_value_atindex(va,i);
  393. }
  394. return r;
  395. }
  396. /*
  397. * Remove any values older than the CSN.
  398. */
  399. int
  400. valuearray_purge(Slapi_Value ***va, const CSN *csn)
  401. {
  402. int numValues=0;
  403. int i=0;
  404. int nextValue=0;
  405. PR_ASSERT(va!=NULL && *va!=NULL);
  406. /* Loop over all the values freeing the old ones. */
  407. for(i=0; (*va)[i]; i++)
  408. {
  409. csnset_purge(&((*va)[i]->v_csnset),csn);
  410. if ((*va)[i]->v_csnset == NULL)
  411. {
  412. slapi_value_free(&(*va)[i]);
  413. (*va)[i] = NULL;
  414. }
  415. }
  416. /* Now compact the value list. */
  417. numValues=i;
  418. nextValue = 0;
  419. i = 0;
  420. for(i=0;i<numValues;i++)
  421. {
  422. while((nextValue < numValues) && (NULL == (*va)[nextValue]))
  423. {
  424. nextValue++;
  425. }
  426. if(nextValue < numValues)
  427. {
  428. (*va)[i] = (*va)[nextValue];
  429. nextValue++;
  430. }
  431. else
  432. {
  433. break;
  434. }
  435. }
  436. (*va)[i] = NULL;
  437. /* All the values were deleted, we can discard the whole array. */
  438. if(NULL == (*va)[0])
  439. {
  440. slapi_ch_free((void**)va);
  441. *va= NULL;
  442. }
  443. return(0);
  444. }
  445. size_t
  446. valuearray_size(Slapi_Value **va)
  447. {
  448. size_t s= 0;
  449. if(va!=NULL && va[0]!=NULL)
  450. {
  451. int i;
  452. for (i = 0; va[i]; i++)
  453. {
  454. s += value_size(va[i]);
  455. }
  456. s += (i + 1) * sizeof(Slapi_Value*);
  457. }
  458. return s;
  459. }
  460. void
  461. valuearray_update_csn(Slapi_Value **va, CSNType t, const CSN *csn)
  462. {
  463. int i;
  464. for (i = 0; va!=NULL && va[i]; i++)
  465. {
  466. value_update_csn(va[i],t,csn);
  467. }
  468. }
  469. /*
  470. * Shunt up the values to cover the empty slots.
  471. *
  472. * "compressed" means "contains no NULL's"
  473. *
  474. * Invariant for the outer loop:
  475. * va[0..i] is compressed &&
  476. * va[n..numvalues] contains just NULL's
  477. *
  478. * Invariant for the inner loop:
  479. * i<j<=k<=n && va[j..k] has been shifted left by (j-i) places &&
  480. * va[k..n] remains to be shifted left by (j-i) places
  481. *
  482. */
  483. void
  484. valuearray_compress(Slapi_Value **va,int numvalues)
  485. {
  486. int i = 0;
  487. int n= numvalues;
  488. while(i<n)
  489. {
  490. if ( va[i] != NULL ) {
  491. i++;
  492. } else {
  493. int k,j;
  494. j = i + 1;
  495. /* Find the length of the next run of NULL's */
  496. while( j<n && va[j] == NULL) { j++; }
  497. /* va[i..j] is all NULL && j<= n */
  498. for ( k = j; k<n; k++ )
  499. {
  500. va[k - (j-i)] = va[k];
  501. va[k] = NULL;
  502. }
  503. /* va[i..n] has been shifted down by j-i places */
  504. n = n - (j-i);
  505. /*
  506. * If va[i] in now non null, then bump i,
  507. * if not then we are done anyway (j==n) so can bump it.
  508. */
  509. i++;
  510. }
  511. }
  512. }
  513. /* <=========================== Value Array Fast ==========================> */
  514. void
  515. valuearrayfast_init(struct valuearrayfast *vaf,Slapi_Value **va)
  516. {
  517. vaf->num= valuearray_count(va);
  518. vaf->max= vaf->num;
  519. vaf->va= va;
  520. }
  521. void
  522. valuearrayfast_done(struct valuearrayfast *vaf)
  523. {
  524. if(vaf->va!=NULL)
  525. {
  526. int i;
  527. for(i=0; i<vaf->num; i++)
  528. {
  529. slapi_value_free(&vaf->va[i]);
  530. }
  531. slapi_ch_free((void **)&vaf->va);
  532. vaf->num= 0;
  533. vaf->max= 0;
  534. }
  535. }
  536. void
  537. valuearrayfast_add_value(struct valuearrayfast *vaf,const Slapi_Value *v)
  538. {
  539. valuearray_add_value_fast(&vaf->va,(Slapi_Value *)v,vaf->num,&vaf->max,0/*Exact*/,0/*!PassIn*/);
  540. vaf->num++;
  541. }
  542. void
  543. valuearrayfast_add_value_passin(struct valuearrayfast *vaf,Slapi_Value *v)
  544. {
  545. valuearray_add_value_fast(&vaf->va,v,vaf->num,&vaf->max,0/*Exact*/,1/*PassIn*/);
  546. vaf->num++;
  547. }
  548. void
  549. valuearrayfast_add_valuearrayfast(struct valuearrayfast *vaf,const struct valuearrayfast *vaf_add)
  550. {
  551. valuearray_add_valuearray_fast(&vaf->va,vaf_add->va,vaf->num,vaf_add->num,&vaf->max,0/*Exact*/,0/*!PassIn*/);
  552. vaf->num+= vaf_add->num;
  553. }
  554. /* <=========================== ValueArrayIndexTree =======================> */
  555. static int valuetree_dupvalue_disallow( caddr_t d1, caddr_t d2 );
  556. static int valuetree_node_cmp( caddr_t d1, caddr_t d2 );
  557. static int valuetree_node_free( caddr_t data );
  558. /*
  559. * structure used within AVL value trees.
  560. */
  561. typedef struct valuetree_node
  562. {
  563. int index; /* index into the value array */
  564. Slapi_Value *sval; /* the actual value */
  565. } valuetree_node;
  566. /*
  567. * Create or update an AVL tree of values that can be used to speed up value
  568. * lookups. We store the index keys for the values in the AVL tree so
  569. * we can use a trivial comparison function.
  570. *
  571. * Returns:
  572. * LDAP_SUCCESS on success,
  573. * LDAP_TYPE_OR_VALUE_EXISTS if the value already exists,
  574. * LDAP_OPERATIONS_ERROR for some unexpected failure.
  575. *
  576. * Sets *valuetreep to the root of the AVL tree that was created. If a
  577. * non-zero value is returned, the tree is freed if free_on_error is non-zero
  578. * and *valuetreep is set to NULL.
  579. */
  580. int
  581. valuetree_add_valuearray( const Slapi_Attr *sattr, Slapi_Value **va, Avlnode **valuetreep, int *duplicate_index )
  582. {
  583. int rc= LDAP_SUCCESS;
  584. PR_ASSERT(sattr!=NULL);
  585. PR_ASSERT(valuetreep!=NULL);
  586. if ( duplicate_index ) {
  587. *duplicate_index = -1;
  588. }
  589. if ( !valuearray_isempty(va) )
  590. {
  591. Slapi_Value **keyvals;
  592. /* Convert the value array into key values */
  593. if ( slapi_attr_values2keys_sv( sattr, (Slapi_Value**)va, &keyvals, LDAP_FILTER_EQUALITY ) != 0 ) /* jcm cast */
  594. {
  595. LDAPDebug( LDAP_DEBUG_ANY,"slapi_attr_values2keys_sv for attribute %s failed\n", sattr->a_type, 0, 0 );
  596. rc= LDAP_OPERATIONS_ERROR;
  597. }
  598. else
  599. {
  600. int i;
  601. valuetree_node *vaip;
  602. for ( i = 0; rc==LDAP_SUCCESS && va[i] != NULL; ++i )
  603. {
  604. if ( keyvals[i] == NULL )
  605. {
  606. LDAPDebug( LDAP_DEBUG_ANY,"slapi_attr_values2keys_sv for attribute %s did not return enough key values\n", sattr->a_type, 0, 0 );
  607. rc= LDAP_OPERATIONS_ERROR;
  608. }
  609. else
  610. {
  611. vaip = (valuetree_node *)slapi_ch_malloc( sizeof( valuetree_node ));
  612. vaip->index = i;
  613. vaip->sval = keyvals[i];
  614. if (( rc = avl_insert( valuetreep, vaip, valuetree_node_cmp, valuetree_dupvalue_disallow )) != 0 )
  615. {
  616. slapi_ch_free( (void **)&vaip );
  617. /* Value must already be in there */
  618. rc= LDAP_TYPE_OR_VALUE_EXISTS;
  619. if ( duplicate_index ) {
  620. *duplicate_index = i;
  621. }
  622. }
  623. else
  624. {
  625. keyvals[i]= NULL;
  626. }
  627. }
  628. }
  629. /* start freeing at index i - the rest of them have already
  630. been moved into valuetreep
  631. the loop iteration will always do the +1, so we have
  632. to remove it if so */
  633. i = (i > 0) ? i-1 : 0;
  634. valuearray_free_ext( &keyvals, i );
  635. }
  636. }
  637. if(rc!=0)
  638. {
  639. valuetree_free( valuetreep );
  640. }
  641. return rc;
  642. }
  643. int
  644. valuetree_add_value( const Slapi_Attr *sattr, const Slapi_Value *v, Avlnode **valuetreep)
  645. {
  646. Slapi_Value *va[2];
  647. va[0]= (Slapi_Value*)v;
  648. va[1]= NULL;
  649. return valuetree_add_valuearray( sattr, va, valuetreep, NULL);
  650. }
  651. /*
  652. *
  653. * Find value "v" using AVL tree "valuetree"
  654. *
  655. * returns LDAP_SUCCESS if "v" was found, LDAP_NO_SUCH_ATTRIBUTE
  656. * if "v" was not found and LDAP_OPERATIONS_ERROR if some unexpected error occurs.
  657. */
  658. static int
  659. valuetree_find( const struct slapi_attr *a, const Slapi_Value *v, Avlnode *valuetree, int *index)
  660. {
  661. const Slapi_Value *oneval[2];
  662. Slapi_Value **keyvals;
  663. valuetree_node *vaip, tmpvain;
  664. PR_ASSERT(a!=NULL);
  665. PR_ASSERT(a->a_plugin!=NULL);
  666. PR_ASSERT(v!=NULL);
  667. PR_ASSERT(valuetree!=NULL);
  668. PR_ASSERT(index!=NULL);
  669. if ( a == NULL || v == NULL || valuetree == NULL )
  670. {
  671. return( LDAP_OPERATIONS_ERROR );
  672. }
  673. keyvals = NULL;
  674. oneval[0] = v;
  675. oneval[1] = NULL;
  676. if ( slapi_attr_values2keys_sv( a, (Slapi_Value**)oneval, &keyvals, LDAP_FILTER_EQUALITY ) != 0 /* jcm cast */
  677. || keyvals == NULL
  678. || keyvals[0] == NULL )
  679. {
  680. LDAPDebug( LDAP_DEBUG_ANY, "valuetree_find_and_replace: "
  681. "slapi_attr_values2keys_sv failed for type %s\n",
  682. a->a_type, 0, 0 );
  683. return( LDAP_OPERATIONS_ERROR );
  684. }
  685. tmpvain.index = 0;
  686. tmpvain.sval = keyvals[0];
  687. vaip = (valuetree_node *)avl_find( valuetree, &tmpvain, valuetree_node_cmp );
  688. if ( keyvals != NULL )
  689. {
  690. valuearray_free( &keyvals );
  691. }
  692. if (vaip == NULL)
  693. {
  694. return( LDAP_NO_SUCH_ATTRIBUTE );
  695. }
  696. else
  697. {
  698. *index= vaip->index;
  699. }
  700. return( LDAP_SUCCESS );
  701. }
  702. static int
  703. valuetree_dupvalue_disallow( caddr_t d1, caddr_t d2 )
  704. {
  705. return( 1 );
  706. }
  707. void
  708. valuetree_free( Avlnode **valuetreep )
  709. {
  710. if ( valuetreep != NULL && *valuetreep != NULL )
  711. {
  712. avl_free( *valuetreep, valuetree_node_free );
  713. *valuetreep = NULL;
  714. }
  715. }
  716. static int
  717. valuetree_node_free( caddr_t data )
  718. {
  719. if ( data!=NULL )
  720. {
  721. valuetree_node *vaip = (valuetree_node *)data;
  722. slapi_value_free(&vaip->sval);
  723. slapi_ch_free( (void **)&data );
  724. }
  725. return( 0 );
  726. }
  727. static int
  728. valuetree_node_cmp( caddr_t d1, caddr_t d2 )
  729. {
  730. const struct berval *bv1, *bv2;
  731. int rc;
  732. bv1 = slapi_value_get_berval(((valuetree_node *)d1)->sval);
  733. bv2 = slapi_value_get_berval(((valuetree_node *)d2)->sval);
  734. if ( bv1->bv_len < bv2->bv_len ) {
  735. rc = -1;
  736. } else if ( bv1->bv_len > bv2->bv_len ) {
  737. rc = 1;
  738. } else {
  739. rc = memcmp( bv1->bv_val, bv2->bv_val, bv1->bv_len );
  740. }
  741. return( rc );
  742. }
  743. /* <=========================== Value Set =======================> */
  744. /*
  745. * JCM: All of these valueset functions are just forwarded to the
  746. * JCM: valuearray functions... waste of time. Inline them!
  747. */
  748. Slapi_ValueSet *
  749. slapi_valueset_new()
  750. {
  751. Slapi_ValueSet *vs = (Slapi_ValueSet *)slapi_ch_calloc(1,sizeof(Slapi_ValueSet));
  752. if(vs)
  753. slapi_valueset_init(vs);
  754. return vs;
  755. }
  756. void
  757. slapi_valueset_init(Slapi_ValueSet *vs)
  758. {
  759. if(vs!=NULL)
  760. {
  761. vs->va= NULL;
  762. }
  763. }
  764. void
  765. slapi_valueset_done(Slapi_ValueSet *vs)
  766. {
  767. if(vs!=NULL)
  768. {
  769. if(vs->va!=NULL)
  770. {
  771. valuearray_free(&vs->va);
  772. vs->va= NULL;
  773. }
  774. }
  775. }
  776. void
  777. slapi_valueset_free(Slapi_ValueSet *vs)
  778. {
  779. if(vs!=NULL)
  780. {
  781. slapi_valueset_done(vs);
  782. slapi_ch_free((void **)&vs);
  783. }
  784. }
  785. void
  786. slapi_valueset_set_from_smod(Slapi_ValueSet *vs, Slapi_Mod *smod)
  787. {
  788. Slapi_Value **va= NULL;
  789. valuearray_init_bervalarray(slapi_mod_get_ldapmod_byref(smod)->mod_bvalues, &va);
  790. valueset_set_valuearray_passin(vs, va);
  791. }
  792. void
  793. valueset_set_valuearray_byval(Slapi_ValueSet *vs, Slapi_Value **addvals)
  794. {
  795. slapi_valueset_init(vs);
  796. valueset_add_valuearray(vs,addvals);
  797. }
  798. void
  799. valueset_set_valuearray_passin(Slapi_ValueSet *vs, Slapi_Value **addvals)
  800. {
  801. slapi_valueset_init(vs);
  802. vs->va= addvals;
  803. }
  804. void
  805. slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
  806. {
  807. slapi_valueset_init(vs1);
  808. valueset_add_valueset(vs1,vs2);
  809. }
  810. int
  811. slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v )
  812. {
  813. return valuearray_first_value(vs->va,v);
  814. }
  815. int
  816. slapi_valueset_next_value( Slapi_ValueSet *vs, int index, Slapi_Value **v)
  817. {
  818. return valuearray_next_value(vs->va,index,v);
  819. }
  820. int
  821. slapi_valueset_count( const Slapi_ValueSet *vs)
  822. {
  823. int r=0;
  824. if (NULL != vs)
  825. {
  826. if(!valuearray_isempty(vs->va))
  827. {
  828. r= valuearray_count(vs->va);
  829. }
  830. }
  831. return r;
  832. }
  833. int
  834. valueset_isempty( const Slapi_ValueSet *vs)
  835. {
  836. return valuearray_isempty(vs->va);
  837. }
  838. Slapi_Value *
  839. slapi_valueset_find(const Slapi_Attr *a, const Slapi_ValueSet *vs, const Slapi_Value *v)
  840. {
  841. Slapi_Value *r= NULL;
  842. if(!valuearray_isempty(vs->va))
  843. {
  844. int i= valuearray_find(a,vs->va,v);
  845. if(i!=-1)
  846. {
  847. r= vs->va[i];
  848. }
  849. }
  850. return r;
  851. }
  852. /*
  853. * The value is found in the set, removed and returned.
  854. * The caller is responsible for freeing the value.
  855. */
  856. Slapi_Value *
  857. valueset_remove_value(const Slapi_Attr *a, Slapi_ValueSet *vs, const Slapi_Value *v)
  858. {
  859. Slapi_Value *r= NULL;
  860. if(!valuearray_isempty(vs->va))
  861. {
  862. r= valuearray_remove_value(a, vs->va, v);
  863. }
  864. return r;
  865. }
  866. /*
  867. * Remove any values older than the CSN.
  868. */
  869. int
  870. valueset_purge(Slapi_ValueSet *vs, const CSN *csn)
  871. {
  872. int r= 0;
  873. if(!valuearray_isempty(vs->va))
  874. {
  875. r= valuearray_purge(&vs->va, csn);
  876. }
  877. return r;
  878. }
  879. Slapi_Value **
  880. valueset_get_valuearray(const Slapi_ValueSet *vs)
  881. {
  882. return (Slapi_Value**)vs->va;
  883. }
  884. size_t
  885. valueset_size(const Slapi_ValueSet *vs)
  886. {
  887. size_t s= 0;
  888. if(!valuearray_isempty(vs->va))
  889. {
  890. s= valuearray_size(vs->va);
  891. }
  892. return s;
  893. }
  894. /*
  895. * The value array is passed in by value.
  896. */
  897. void
  898. valueset_add_valuearray(Slapi_ValueSet *vs, Slapi_Value **addvals)
  899. {
  900. if(!valuearray_isempty(addvals))
  901. {
  902. valuearray_add_valuearray(&vs->va, addvals, 0);
  903. }
  904. }
  905. void
  906. valueset_add_valuearray_ext(Slapi_ValueSet *vs, Slapi_Value **addvals, PRUint32 flags)
  907. {
  908. if(!valuearray_isempty(addvals))
  909. {
  910. valuearray_add_valuearray(&vs->va, addvals, flags);
  911. }
  912. }
  913. /*
  914. * The value is passed in by value.
  915. */
  916. void
  917. slapi_valueset_add_value(Slapi_ValueSet *vs, const Slapi_Value *addval)
  918. {
  919. valuearray_add_value(&vs->va,addval);
  920. }
  921. void
  922. slapi_valueset_add_value_ext(Slapi_ValueSet *vs, Slapi_Value *addval, unsigned long flags)
  923. {
  924. Slapi_Value *oneval[2];
  925. oneval[0]= (Slapi_Value*)addval;
  926. oneval[1]= NULL;
  927. valuearray_add_valuearray(&vs->va, oneval, flags);
  928. }
  929. /*
  930. * The string is passed in by value.
  931. */
  932. void
  933. valueset_add_string(Slapi_ValueSet *vs, const char *s, CSNType t, const CSN *csn)
  934. {
  935. Slapi_Value v;
  936. value_init(&v,NULL,t,csn);
  937. slapi_value_set_string(&v,s);
  938. valuearray_add_value(&vs->va,&v);
  939. value_done(&v);
  940. }
  941. /*
  942. * The value set is passed in by value.
  943. */
  944. void
  945. valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
  946. {
  947. if (vs1 && vs2)
  948. valueset_add_valuearray(vs1, vs2->va);
  949. }
  950. void
  951. valueset_remove_string(const Slapi_Attr *a, Slapi_ValueSet *vs, const char *s)
  952. {
  953. Slapi_Value v;
  954. Slapi_Value *removed;
  955. value_init(&v,NULL,CSN_TYPE_NONE,NULL);
  956. slapi_value_set_string(&v,s);
  957. removed = valuearray_remove_value(a, vs->va, &v);
  958. if(removed) {
  959. slapi_value_free(&removed);
  960. }
  961. value_done(&v);
  962. }
  963. void
  964. valueset_update_csn(Slapi_ValueSet *vs, CSNType t, const CSN *csn)
  965. {
  966. if(!valuearray_isempty(vs->va))
  967. {
  968. valuearray_update_csn(vs->va,t,csn);
  969. }
  970. }
  971. /*
  972. * Remove an array of values from a value set.
  973. * The removed values are passed back in an array.
  974. *
  975. * Flags
  976. * SLAPI_VALUE_FLAG_PRESERVECSNSET - csnset in the value set is duplicated and
  977. * preserved in the matched element of the
  978. * array of values.
  979. * SLAPI_VALUE_FLAG_IGNOREERROR - ignore an error: Couldn't find the value to
  980. * be deleted.
  981. * SLAPI_VALUE_FLAG_USENEWVALUE - replace the value between the value set and
  982. * the matched element of the array of values
  983. * (used by entry_add_present_values_wsi).
  984. *
  985. * Returns
  986. * LDAP_SUCCESS - OK.
  987. * LDAP_NO_SUCH_ATTRIBUTE - A value to be deleted was not in the value set.
  988. * LDAP_OPERATIONS_ERROR - Something very bad happened.
  989. */
  990. int
  991. valueset_remove_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slapi_Value **valuestodelete, int flags, Slapi_Value ***va_out)
  992. {
  993. int rc= LDAP_SUCCESS;
  994. if(!valuearray_isempty(vs->va))
  995. {
  996. int numberofvaluestodelete= valuearray_count(valuestodelete);
  997. struct valuearrayfast vaf_out;
  998. if ( va_out )
  999. {
  1000. valuearrayfast_init(&vaf_out,*va_out);
  1001. }
  1002. /*
  1003. * If there are more then one values, build an AVL tree to check
  1004. * the duplicated values.
  1005. */
  1006. if ( numberofvaluestodelete > 1 )
  1007. {
  1008. /*
  1009. * Several values to delete: first build an AVL tree that
  1010. * holds all of the existing values and use that to find
  1011. * the values we want to delete.
  1012. */
  1013. Avlnode *vtree = NULL;
  1014. int numberofexistingvalues= slapi_valueset_count(vs);
  1015. rc= valuetree_add_valuearray( a, vs->va, &vtree, NULL );
  1016. if ( rc!=LDAP_SUCCESS )
  1017. {
  1018. /*
  1019. * failed while constructing AVL tree of existing
  1020. * values... something bad happened.
  1021. */
  1022. rc= LDAP_OPERATIONS_ERROR;
  1023. }
  1024. else
  1025. {
  1026. int i;
  1027. /*
  1028. * find and mark all the values that are to be deleted
  1029. */
  1030. for ( i = 0; rc == LDAP_SUCCESS && valuestodelete[i] != NULL; ++i )
  1031. {
  1032. int index= 0;
  1033. rc = valuetree_find( a, valuestodelete[i], vtree, &index );
  1034. if(rc==LDAP_SUCCESS)
  1035. {
  1036. if(vs->va[index]!=NULL)
  1037. {
  1038. /* Move the value to be removed to the out array */
  1039. if ( va_out )
  1040. {
  1041. if (vs->va[index]->v_csnset &&
  1042. (flags & (SLAPI_VALUE_FLAG_PRESERVECSNSET|
  1043. SLAPI_VALUE_FLAG_USENEWVALUE)))
  1044. {
  1045. valuestodelete[i]->v_csnset = csnset_dup (vs->va[index]->v_csnset);
  1046. }
  1047. if (flags & SLAPI_VALUE_FLAG_USENEWVALUE)
  1048. {
  1049. valuearrayfast_add_value_passin(&vaf_out,valuestodelete[i]);
  1050. valuestodelete[i] = vs->va[index];
  1051. vs->va[index] = NULL;
  1052. }
  1053. else
  1054. {
  1055. valuearrayfast_add_value_passin(&vaf_out,vs->va[index]);
  1056. vs->va[index] = NULL;
  1057. }
  1058. }
  1059. else
  1060. {
  1061. if (flags & SLAPI_VALUE_FLAG_PRESERVECSNSET)
  1062. {
  1063. valuestodelete[i]->v_csnset = vs->va[index]->v_csnset;
  1064. vs->va[index]->v_csnset = NULL;
  1065. }
  1066. slapi_value_free ( & vs->va[index] );
  1067. }
  1068. }
  1069. else
  1070. {
  1071. /* We already deleted this value... */
  1072. if((flags & SLAPI_VALUE_FLAG_IGNOREERROR) == 0)
  1073. {
  1074. /* ...that's an error. */
  1075. rc= LDAP_NO_SUCH_ATTRIBUTE;
  1076. }
  1077. }
  1078. }
  1079. else
  1080. {
  1081. /* Couldn't find the value to be deleted */
  1082. if(rc==LDAP_NO_SUCH_ATTRIBUTE && (flags & SLAPI_VALUE_FLAG_IGNOREERROR ))
  1083. {
  1084. rc= LDAP_SUCCESS;
  1085. }
  1086. }
  1087. }
  1088. valuetree_free( &vtree );
  1089. if ( rc != LDAP_SUCCESS )
  1090. {
  1091. LDAPDebug( LDAP_DEBUG_ANY,"could not find value %d for attr %s (%s)\n", i-1, a->a_type, ldap_err2string( rc ));
  1092. }
  1093. else
  1094. {
  1095. /* Shunt up all the remaining values to cover the deleted ones. */
  1096. valuearray_compress(vs->va,numberofexistingvalues);
  1097. }
  1098. }
  1099. }
  1100. else
  1101. {
  1102. /* We delete one or no value, so we use brute force. */
  1103. int i;
  1104. for ( i = 0; rc==LDAP_SUCCESS && valuestodelete[i] != NULL; ++i )
  1105. {
  1106. Slapi_Value *found= valueset_remove_value(a, vs, valuestodelete[i]);
  1107. if(found!=NULL)
  1108. {
  1109. if ( va_out )
  1110. {
  1111. if (found->v_csnset &&
  1112. (flags & (SLAPI_VALUE_FLAG_PRESERVECSNSET|
  1113. SLAPI_VALUE_FLAG_USENEWVALUE)))
  1114. {
  1115. valuestodelete[i]->v_csnset = csnset_dup (found->v_csnset);
  1116. }
  1117. if (flags & SLAPI_VALUE_FLAG_USENEWVALUE)
  1118. {
  1119. valuearrayfast_add_value_passin(&vaf_out,valuestodelete[i]);
  1120. valuestodelete[i] = found;
  1121. }
  1122. else
  1123. {
  1124. valuearrayfast_add_value_passin(&vaf_out,found);
  1125. }
  1126. }
  1127. else
  1128. {
  1129. if (flags & SLAPI_VALUE_FLAG_PRESERVECSNSET)
  1130. {
  1131. valuestodelete[i]->v_csnset = found->v_csnset;
  1132. found->v_csnset = NULL;
  1133. }
  1134. slapi_value_free ( & found );
  1135. }
  1136. }
  1137. else
  1138. {
  1139. if((flags & SLAPI_VALUE_FLAG_IGNOREERROR) == 0)
  1140. {
  1141. LDAPDebug( LDAP_DEBUG_ARGS,"could not find value %d for attr %s\n", i-1, a->a_type, 0 );
  1142. rc= LDAP_NO_SUCH_ATTRIBUTE;
  1143. }
  1144. }
  1145. }
  1146. }
  1147. if ( va_out )
  1148. {
  1149. *va_out= vaf_out.va;
  1150. if(rc!=LDAP_SUCCESS)
  1151. {
  1152. valuearray_free(va_out);
  1153. }
  1154. }
  1155. }
  1156. return rc;
  1157. }
  1158. /*
  1159. * Check if the set of values in the valueset and the valuearray intersect.
  1160. *
  1161. * Returns
  1162. * LDAP_SUCCESS - No intersection.
  1163. * LDAP_NO_SUCH_ATTRIBUTE - There is an intersection.
  1164. * LDAP_OPERATIONS_ERROR - There are duplicate values in the value set already.
  1165. */
  1166. int
  1167. valueset_intersectswith_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slapi_Value **values, int *duplicate_index )
  1168. {
  1169. int rc= LDAP_SUCCESS;
  1170. if ( duplicate_index ) {
  1171. *duplicate_index = -1;
  1172. }
  1173. if(valuearray_isempty(vs->va))
  1174. {
  1175. /* No intersection */
  1176. }
  1177. else
  1178. {
  1179. int numberofvalues= valuearray_count(values);
  1180. /*
  1181. * determine whether we should use an AVL tree of values or not
  1182. */
  1183. if (numberofvalues==0)
  1184. {
  1185. /* No intersection */
  1186. }
  1187. else if ( numberofvalues > 1 )
  1188. {
  1189. /*
  1190. * Several values to add: use an AVL tree to detect duplicates.
  1191. */
  1192. Avlnode *vtree = NULL;
  1193. rc= valuetree_add_valuearray( a, vs->va, &vtree, duplicate_index );
  1194. if(rc==LDAP_OPERATIONS_ERROR)
  1195. {
  1196. /* There were already duplicate values in the value set */
  1197. }
  1198. else
  1199. {
  1200. rc= valuetree_add_valuearray( a, values, &vtree, duplicate_index );
  1201. /*
  1202. * Returns LDAP_OPERATIONS_ERROR if something very bad happens.
  1203. * Or LDAP_TYPE_OR_VALUE_EXISTS if a value already exists.
  1204. */
  1205. }
  1206. valuetree_free( &vtree );
  1207. }
  1208. else
  1209. {
  1210. /*
  1211. * One value to add: don't bother constructing
  1212. * an AVL tree, etc. since it probably isn't worth the time.
  1213. *
  1214. * JCM - This is actually quite slow because the comparison function is looked up many times.
  1215. */
  1216. int i;
  1217. for ( i = 0; rc == LDAP_SUCCESS && values[i] != NULL; ++i )
  1218. {
  1219. if(valuearray_find(a, vs->va, values[i])!=-1)
  1220. {
  1221. rc = LDAP_TYPE_OR_VALUE_EXISTS;
  1222. *duplicate_index = i;
  1223. break;
  1224. }
  1225. }
  1226. }
  1227. }
  1228. return rc;
  1229. }
  1230. Slapi_ValueSet *
  1231. valueset_dup(const Slapi_ValueSet *dupee)
  1232. {
  1233. Slapi_ValueSet *duped= (Slapi_ValueSet *)slapi_ch_calloc(1,sizeof(Slapi_ValueSet));
  1234. if (NULL!=duped)
  1235. {
  1236. valueset_add_valuearray( duped, dupee->va );
  1237. }
  1238. return duped;
  1239. }
  1240. /* quickly throw away any old contents of this valueset, and stick in the
  1241. * new ones.
  1242. *
  1243. * return value: LDAP_SUCCESS - OK
  1244. * : LDAP_OPERATIONS_ERROR - duplicated values given
  1245. */
  1246. int
  1247. valueset_replace(Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_Value **valstoreplace)
  1248. {
  1249. int rc = LDAP_SUCCESS;
  1250. int numberofvalstoreplace= valuearray_count(valstoreplace);
  1251. /* verify the given values are not duplicated.
  1252. if replacing with one value, no need to check. just replace it.
  1253. */
  1254. if (numberofvalstoreplace > 1)
  1255. {
  1256. Avlnode *vtree = NULL;
  1257. rc = valuetree_add_valuearray( a, valstoreplace, &vtree, NULL );
  1258. valuetree_free(&vtree);
  1259. if ( LDAP_SUCCESS != rc &&
  1260. /* bz 247413: don't override LDAP_TYPE_OR_VALUE_EXISTS */
  1261. LDAP_TYPE_OR_VALUE_EXISTS != rc )
  1262. {
  1263. /* There were already duplicate values in the value set */
  1264. rc = LDAP_OPERATIONS_ERROR;
  1265. }
  1266. }
  1267. if ( rc == LDAP_SUCCESS )
  1268. {
  1269. /* values look good - replace the values in the attribute */
  1270. if(!valuearray_isempty(vs->va))
  1271. {
  1272. /* remove old values */
  1273. slapi_valueset_done(vs);
  1274. }
  1275. /* we now own valstoreplace */
  1276. vs->va = valstoreplace;
  1277. }
  1278. else
  1279. {
  1280. /* caller expects us to own valstoreplace - since we cannot
  1281. use them, just delete them */
  1282. valuearray_free(&valstoreplace);
  1283. }
  1284. return rc;
  1285. }
  1286. /*
  1287. * Search the value set for each value to be update,
  1288. * and update the value with the CSN provided.
  1289. * Updated values are moved from the valuestoupdate
  1290. * array to the valueupdated array.
  1291. */
  1292. void
  1293. valueset_update_csn_for_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slapi_Value **valuestoupdate, CSNType t, const CSN *csn, Slapi_Value ***valuesupdated)
  1294. {
  1295. if(!valuearray_isempty(valuestoupdate) &&
  1296. !valuearray_isempty(vs->va))
  1297. {
  1298. /*
  1299. * determine whether we should use an AVL tree of values or not
  1300. */
  1301. struct valuearrayfast vaf_valuesupdated;
  1302. int numberofvaluestoupdate= valuearray_count(valuestoupdate);
  1303. valuearrayfast_init(&vaf_valuesupdated,*valuesupdated);
  1304. if (numberofvaluestoupdate > 1) /* multiple values to update */
  1305. {
  1306. int i;
  1307. Avlnode *vtree = NULL;
  1308. int rc= valuetree_add_valuearray( a, vs->va, &vtree, NULL );
  1309. PR_ASSERT(rc==LDAP_SUCCESS);
  1310. for (i=0;valuestoupdate[i]!=NULL;++i)
  1311. {
  1312. int index= 0;
  1313. rc = valuetree_find( a, valuestoupdate[i], vtree, &index );
  1314. if(rc==LDAP_SUCCESS)
  1315. {
  1316. value_update_csn(vs->va[index],t,csn);
  1317. valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]);
  1318. valuestoupdate[i] = NULL;
  1319. }
  1320. }
  1321. valuetree_free(&vtree);
  1322. }
  1323. else
  1324. {
  1325. int i;
  1326. for (i=0;valuestoupdate[i]!=NULL;++i)
  1327. {
  1328. int index= valuearray_find(a, vs->va, valuestoupdate[i]);
  1329. if(index!=-1)
  1330. {
  1331. value_update_csn(vs->va[index],t,csn);
  1332. valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]);
  1333. valuestoupdate[i]= NULL;
  1334. }
  1335. }
  1336. }
  1337. valuearray_compress(valuestoupdate,numberofvaluestoupdate);
  1338. *valuesupdated= vaf_valuesupdated.va;
  1339. }
  1340. }
  1341. int
  1342. valuearray_dn_normalize_value(Slapi_Value **vals)
  1343. {
  1344. int rc = 0;
  1345. Slapi_Value **vp = NULL;
  1346. for (vp = vals; vp && *vp; vp++) {
  1347. rc |= value_dn_normalize_value(*vp);
  1348. }
  1349. return rc;
  1350. }