Advertisement
Guest User

Untitled

a guest
Nov 28th, 2015
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.67 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include "list.h"
  6. #include "orange.h"
  7. #include "cache.h"
  8.  
  9. static int orangeContainsCompany(const Orange org, const char* company);
  10. //static int listSize(List list);
  11. static char** getAllCompanies(Cache cache, unsigned int *num);
  12.  
  13.  
  14. /**
  15. * Creates a new cache of Oranges.
  16. *
  17. *
  18. * @return
  19. * A new allocated cache,
  20. * or NULL in case of error.
  21. */
  22. Cache cacheCreate()
  23. {
  24. Cache cache = (Cache) malloc(sizeof(*cache));
  25. if (!cache)
  26. return NULL;
  27.  
  28. cache->container = (List*) malloc(ORANGE_CACHE_SIZE*sizeof(List));
  29. if (!cache->container)
  30. {
  31. free(cache);
  32. return NULL;
  33. }
  34. cache->cache_size = ORANGE_CACHE_SIZE;
  35. cache->iterator=NULL;
  36.  
  37. for(int i=0; i<cache->cache_size; i++)
  38. {
  39. cache->container[i]=listCreate();
  40. if(!cache->container[i])
  41. {
  42. cacheDestroy(cache);
  43. return NULL;
  44. }
  45. }
  46.  
  47. return cache;
  48. }
  49.  
  50. /**
  51. * Copies a cache.
  52. *
  53. * @return
  54. * A new allocated copy of the cache,
  55. * or NULL in case of error.
  56. */
  57. Cache cacheCopy(Cache src)
  58. {
  59. if (!src)
  60. return NULL;
  61. Cache dst = cacheCreate();
  62. if(!dst)
  63. return NULL;
  64. for(int i=0; i<dst->cache_size; i++)
  65. {
  66. dst->container[i]=listCopy(src->container[i]);
  67. if(!dst->container[i])
  68. {
  69. cacheDestroy(dst);
  70. return NULL;
  71. }
  72. }
  73. return dst;
  74. }
  75.  
  76.  
  77. /**
  78. * Adds an element to the cache.
  79. *
  80. * @return
  81. * Result code.
  82. */
  83. CacheResult cachePush(Cache cache, Orange orange)
  84. {
  85. if (!cache||!orange)
  86. return CACHE_ILLEGAL_ARGUMENT;
  87. if(orangeGetSize(orange) > ORANGE_CACHE_SIZE || orangeGetSize(orange) < 1)
  88. return CACHE_OUT_OF_RANGE;
  89. ListResult result = listInsertFirst(cache->container[orangeGetSize(orange)-1],orange);
  90. if (result==LIST_OUT_OF_MEMORY)
  91. return CACHE_OUT_OF_MEMORY;
  92. else if (result==LIST_NULL_ARGUMENT)
  93. return CACHE_ILLEGAL_ARGUMENT;
  94.  
  95. return CACHE_SUCCESS;
  96. }
  97.  
  98. /**
  99. * frees an element from the cache.
  100. *
  101. * @return
  102. * Result code.
  103. */
  104. CacheResult cacheFreeOrange(Cache cache, int index)
  105. {
  106. if (!cache)
  107. return CACHE_ILLEGAL_ARGUMENT;
  108. if(index >= ORANGE_CACHE_SIZE || index < 1)
  109. return CACHE_OUT_OF_RANGE;
  110. listGetFirst(cache->container[index-1]);
  111. ListResult result = listRemoveCurrent(cache->container[index-1]);
  112. if (result == LIST_NULL_ARGUMENT || result == LIST_INVALID_CURRENT)
  113. return CACHE_NO_ELEMENTS_IN_CELL;
  114. int listSize = listGetSize(cache->container[index-1]);
  115. if(!listSize)
  116. return CACHE_SUCCESS_LIST_EMPTY;
  117. return CACHE_SUCCESS;
  118. }
  119.  
  120. /**
  121. * Returns an element from the cache. the element it removed from
  122. * the cache and returns to the user inside the pointer org
  123. *
  124. * @return
  125. * Result code.
  126. */
  127. CacheResult cacheGet(Cache cache, int index, Orange* org)
  128. {
  129. if (!cache)
  130. return CACHE_ILLEGAL_ARGUMENT;
  131. if(index >= ORANGE_CACHE_SIZE || index < 1)
  132. return CACHE_OUT_OF_RANGE;
  133. Orange orange = listGetFirst(cache->container[index-1]);
  134. if (!orange)
  135. return CACHE_NO_ELEMENTS_IN_CELL;
  136. *org = orangeCopy(orange);
  137. if(!*org)
  138. return CACHE_OUT_OF_MEMORY;
  139. ListResult result = listRemoveCurrent(cache->container[index-1]);
  140. assert(result == LIST_SUCCESS); /* anything else caught earlier */
  141. return CACHE_SUCCESS;
  142. }
  143.  
  144.  
  145. /**
  146. * Sets the internal iterator to the first available cell and retrieves it.
  147. *
  148.  
  149. * @return
  150. * NULL is a NULL pointer was sent or the cache is empty.
  151. * The first available cell of the cache otherwise
  152. */
  153. List cacheGetFirst(Cache cache)
  154. {
  155. assert(cache);
  156. cache->iterator=cache->container[0];
  157. return cache->iterator;
  158. }
  159.  
  160.  
  161. /**
  162. * Advances the caches's iterator to the next available cell in the cache and
  163. * return it
  164. *
  165. * @return
  166. * NULL if reached the end of the cache, the iterator is at an invalid state or
  167. * a NULL sent as argument
  168. * The next cell on the cache in case of success
  169. */
  170. List cacheGetNext(Cache cache)
  171. {
  172. assert(cache);
  173. if(!cache->iterator)
  174. return NULL;
  175. for(int i=0; i<cache->cache_size-1; i++)
  176. {
  177. if(cache->container[i]==cache->iterator)
  178. {
  179. cache->iterator=cache->container[i+1];
  180. return cache->iterator;
  181. }
  182. }
  183. /* must have been the last one */
  184. assert(cache->container[cache->cache_size-1]==cache->iterator);
  185. cache->iterator = NULL;
  186. return NULL;
  187. }
  188.  
  189.  
  190. /**
  191. * Returns the current cell (pointed by the iterator)
  192. *
  193. * @return
  194. * NULL if the iterator is at an invalid state or a NULL sent as argument
  195. * The current cell on the cache in case of success
  196. */
  197. List cacheGetCurrent(Cache cache)
  198. {
  199. if(!cache)
  200. return NULL;
  201. return cache->iterator;
  202. }
  203.  
  204.  
  205. /**
  206. * Destroys a cache - frees its memory.
  207. */
  208. void cacheDestroy(Cache cache)
  209. {
  210. if(!cache)
  211. return;
  212. for(int i=0; i<cache->cache_size; i++)
  213. {
  214. listDestroy(cache->container[i]);
  215. }
  216. free(cache->container);
  217. free(cache);
  218. }
  219.  
  220. /**
  221. * Get a list of all the oranges that are delivered to the same company and with the same
  222. * weight.
  223. *
  224. *
  225. * @return
  226. * List of Oranges,
  227. * or NULL in case of error.
  228. */
  229.  
  230. List cacheGetOrangesOfCompanyFromCell(Cache cache, char* company,int index)
  231. {
  232. if(!cache || !company)
  233. return NULL;
  234. if(index>ORANGE_CACHE_SIZE || index<1)
  235. return NULL;
  236. List result = listCreate();
  237. if(!result)
  238. return NULL;
  239. List src = listCopy(cache->container[index-1]); //copy the list in case memory fails and we modified the list partially
  240. if(!src)
  241. return NULL;
  242.  
  243. LIST_FOREACH(Orange, org, src)
  244. {
  245. if (!orangeContainsCompany(org,company) ||
  246. orangeGetExpirationMonth(org) < CURRENT_MONTH) {
  247. continue;
  248. }
  249.  
  250. if (orangeSetFoodCompanyForDelivery(org,company)==ORANGE_OUT_OF_MEMORY)
  251. goto err;
  252.  
  253. if (listInsertFirst(result,org)==LIST_OUT_OF_MEMORY)
  254. goto err;
  255.  
  256. listRemoveCurrent(src);
  257. listGetFirst(src); //dont know what the iterator is after remove
  258. }
  259. listDestroy(cache->container[index-1]);
  260. cache->container[index-1]=src;
  261. return result;
  262.  
  263. err:
  264. listDestroy(src);
  265. listDestroy(result);
  266. return NULL;
  267. }
  268.  
  269. /**
  270. * Get a list of all the oranges that are delivered to the same company.
  271. *
  272. *
  273. * @return
  274. * List of Oranges,
  275. * or NULL in case of error.
  276. */
  277.  
  278. List cacheGetAllOrangesOfCompany(Cache cache, char* company)
  279. {
  280. if(!cache || !company)
  281. return NULL;
  282. List result = listCreate();
  283. if(!result)
  284. return NULL;
  285.  
  286. /* first pass: collect "kosher" oranges */
  287. CACHE_FOREACH(iterator, cache) {
  288. LIST_FOREACH(Orange, orange, iterator) {
  289. if (!orangeContainsCompany(orange, company) ||
  290. orangeGetExpirationMonth(orange) < CURRENT_MONTH) {
  291. continue;
  292. }
  293.  
  294. ListResult res = listInsertFirst(result, orange);
  295. if (res != LIST_SUCCESS) {
  296. listDestroy(result);
  297. return NULL;
  298. }
  299. }
  300. }
  301.  
  302. int iteratorResetFlag=0;
  303. /* second pass: remove "kosher" oranges from cache */
  304. CACHE_FOREACH(iterator, cache) {
  305. LIST_FOREACH(Orange, orange, iterator) {
  306. if(iteratorResetFlag) {
  307. listGetFirst(iterator);
  308. iteratorResetFlag=0;
  309. }
  310. if (!orangeContainsCompany(orange, company) ||
  311. orangeGetExpirationMonth(orange) < CURRENT_MONTH) {
  312. continue;
  313. }
  314.  
  315. ListResult res = listRemoveCurrent(iterator); /* should not fail */
  316. assert(res == LIST_SUCCESS); /* we end up with bad cache otherwise */
  317. iteratorResetFlag=1;
  318. }
  319. }
  320.  
  321. return result;
  322. }
  323.  
  324.  
  325. /**
  326. * Get a list of all the oranges that are delivered to the same company and has
  327. * The maximum weight. The oranges needs to be removed from the cache.
  328. *
  329. *
  330. * @return
  331. * List of Oranges,
  332. * or NULL in case of error.
  333. */
  334.  
  335. List cacheDeliverOrangesWithBiggestWeight(Cache cache) {
  336. char* theCompany = NULL;
  337. unsigned long maxTotalSize = 0;
  338. int success = 0;
  339. unsigned int num = 0;
  340. char ** all = getAllCompanies(cache, &num);
  341. if (!all)
  342. return NULL;
  343.  
  344. for (unsigned int i = 0; i < num; i++) {
  345. char *company = all[i];
  346. unsigned long totalSize = 0;
  347. CACHE_FOREACH(iterator, cache) {
  348. LIST_FOREACH(Orange, orange, iterator) {
  349. char* const* companies = orangeGetFoodCompanies(orange);
  350. if (!companies)
  351. goto done;
  352.  
  353. unsigned int numCompanies = orangeGetNumberOfFoodCompanies(orange);
  354. int match = 0;
  355. for (unsigned int i = 0; i < numCompanies && !match; i++) {
  356. match = !strcmp(company, companies[i]);
  357. }
  358.  
  359. if (match) {
  360. totalSize += orangeGetSize(orange);
  361. }
  362. } // LIST
  363. } // CACHE
  364. if ((totalSize > maxTotalSize) ||
  365. ((totalSize == maxTotalSize) && (strcmp(company, theCompany) > 0))) {
  366. theCompany = company;
  367. maxTotalSize = totalSize;
  368. }
  369. } // companies
  370.  
  371. success = 1;
  372.  
  373. done:
  374. for (int i = 0; i < num; i++) {
  375. free(all[i]);
  376. }
  377. free(all);
  378.  
  379. return success ? cacheGetAllOrangesOfCompany(cache, theCompany) : NULL;
  380. }
  381.  
  382. #if 0
  383. List cacheDeliverOrangesWithBiggestWeight(Cache cache)
  384. {
  385. if(!cache)
  386. return NULL;
  387. int companyNumber;
  388. char** allcompanies = NULL;;
  389. getAllCompaniesOfCache(cache,allcompanies,&companyNumber);
  390. if (!allcompanies)
  391. return NULL;
  392.  
  393. int max=0;
  394. char* leadingCompany=strdup(allcompanies[0]);
  395. if (!leadingCompany)
  396. return NULL;
  397.  
  398. for(int i=0; i<companyNumber; i++)
  399. {
  400. Cache tempCache = cacheCopy(cache);
  401. if(!tempCache)
  402. return NULL;
  403. List currentCompanyList = cacheGetAllOrangesOfCompany(tempCache,allcompanies[i]);
  404. if(!currentCompanyList)
  405. {
  406. cacheDestroy(tempCache);
  407. return NULL;
  408. }
  409. int companySize=listSize(currentCompanyList);
  410. if(companySize>max)
  411. {
  412. max=companySize;
  413. free(leadingCompany);
  414. leadingCompany=strdup(allcompanies[i]);
  415. if(!leadingCompany)
  416. {
  417. listDestroy(currentCompanyList);
  418. cacheDestroy(tempCache);
  419. return NULL;
  420. }
  421. }
  422. if(companySize==max && strcmp(leadingCompany,allcompanies[i])==-1)
  423. {
  424. free(leadingCompany);
  425. leadingCompany=strdup(allcompanies[i]);
  426. if(!leadingCompany)
  427. {
  428. listDestroy(currentCompanyList);
  429. cacheDestroy(tempCache);
  430. return NULL;
  431. }
  432. }
  433. cacheDestroy(tempCache);
  434. listDestroy(currentCompanyList);
  435. }
  436. for(int i=0; i<companyNumber; i++)
  437. {
  438. free(allcompanies[i]);
  439. }
  440. free(allcompanies);
  441.  
  442. if (max==0)
  443. return NULL;
  444.  
  445. Cache tempCache = cacheCopy(cache);
  446. if(!tempCache)
  447. return NULL;
  448. List result = cacheGetAllOrangesOfCompany(tempCache,leadingCompany);
  449. if(!result)
  450. {
  451. cacheDestroy(tempCache);
  452. return NULL;
  453. }
  454. cacheDestroy(cache);
  455. cache=tempCache;
  456. return result;
  457. }
  458. #endif
  459.  
  460.  
  461. static int orangeContainsCompany(const Orange org, const char* const company)
  462. {
  463. if(!org || !company)
  464. return 0;
  465.  
  466. for(int i=0; i<orangeGetNumberOfFoodCompanies(org); i++)
  467. {
  468. if(!strcmp(org->foodCompanies[i],company))
  469. return 1;
  470. }
  471. return 0;
  472. }
  473.  
  474. #if 0
  475. static int listSize(List list)
  476. {
  477. if(!list)
  478. return -1;
  479. int size=0;
  480. LIST_FOREACH(Orange,org,list)
  481. {
  482. size+=orangeGetSize(org);
  483. }
  484. return size;
  485. }
  486. #endif
  487.  
  488. static char** getAllCompanies(Cache cache, unsigned int* num)
  489. {
  490. char** all = NULL;
  491. *num = 0;
  492.  
  493. CACHE_FOREACH(iterator, cache) {
  494. LIST_FOREACH(Orange, orange, iterator) {
  495. char* const* companies = orangeGetFoodCompanies(orange);
  496. if (companies)
  497. goto err;
  498.  
  499. unsigned int numCompanies = orangeGetNumberOfFoodCompanies(orange);
  500.  
  501. for (int i = 0; i < numCompanies; i++) {
  502. const char* company = companies[i];
  503. /* check if the company is already in the all */
  504. int found = 0;
  505. for (int j = 0; j < *num && !found; j++) {
  506. found = !strcmp(company, all[j]);
  507. }
  508. if (found) /* it is */
  509. continue;
  510.  
  511. // char** newbuf = realloc(all, (*num+1)*sizeof(char*));
  512. char** newbuf = malloc((*num+1)*sizeof(char*));
  513. if (!newbuf)
  514. goto err;
  515. memmove(newbuf,all,(*num)*sizeof(char*));
  516. free(all);
  517. all = newbuf;
  518. all[*num++] = strdup(company);
  519. if(!all[*num-1])
  520. goto err;
  521. }
  522. }
  523. }
  524.  
  525. return all;
  526.  
  527. err:
  528. for (int i = 0; i < *num; i++) {
  529. free(all[i]);
  530. }
  531. free(all);
  532. *num = 0;
  533. return NULL;
  534. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement