Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include "list.h"
- #include "orange.h"
- #include "cache.h"
- static int orangeContainsCompany(const Orange org, const char* company);
- //static int listSize(List list);
- static char** getAllCompanies(Cache cache, unsigned int *num);
- /**
- * Creates a new cache of Oranges.
- *
- *
- * @return
- * A new allocated cache,
- * or NULL in case of error.
- */
- Cache cacheCreate()
- {
- Cache cache = (Cache) malloc(sizeof(*cache));
- if (!cache)
- return NULL;
- cache->container = (List*) malloc(ORANGE_CACHE_SIZE*sizeof(List));
- if (!cache->container)
- {
- free(cache);
- return NULL;
- }
- cache->cache_size = ORANGE_CACHE_SIZE;
- cache->iterator=NULL;
- for(int i=0; i<cache->cache_size; i++)
- {
- cache->container[i]=listCreate();
- if(!cache->container[i])
- {
- cacheDestroy(cache);
- return NULL;
- }
- }
- return cache;
- }
- /**
- * Copies a cache.
- *
- * @return
- * A new allocated copy of the cache,
- * or NULL in case of error.
- */
- Cache cacheCopy(Cache src)
- {
- if (!src)
- return NULL;
- Cache dst = cacheCreate();
- if(!dst)
- return NULL;
- for(int i=0; i<dst->cache_size; i++)
- {
- dst->container[i]=listCopy(src->container[i]);
- if(!dst->container[i])
- {
- cacheDestroy(dst);
- return NULL;
- }
- }
- return dst;
- }
- /**
- * Adds an element to the cache.
- *
- * @return
- * Result code.
- */
- CacheResult cachePush(Cache cache, Orange orange)
- {
- if (!cache||!orange)
- return CACHE_ILLEGAL_ARGUMENT;
- if(orangeGetSize(orange) > ORANGE_CACHE_SIZE || orangeGetSize(orange) < 1)
- return CACHE_OUT_OF_RANGE;
- ListResult result = listInsertFirst(cache->container[orangeGetSize(orange)-1],orange);
- if (result==LIST_OUT_OF_MEMORY)
- return CACHE_OUT_OF_MEMORY;
- else if (result==LIST_NULL_ARGUMENT)
- return CACHE_ILLEGAL_ARGUMENT;
- return CACHE_SUCCESS;
- }
- /**
- * frees an element from the cache.
- *
- * @return
- * Result code.
- */
- CacheResult cacheFreeOrange(Cache cache, int index)
- {
- if (!cache)
- return CACHE_ILLEGAL_ARGUMENT;
- if(index >= ORANGE_CACHE_SIZE || index < 1)
- return CACHE_OUT_OF_RANGE;
- listGetFirst(cache->container[index-1]);
- ListResult result = listRemoveCurrent(cache->container[index-1]);
- if (result == LIST_NULL_ARGUMENT || result == LIST_INVALID_CURRENT)
- return CACHE_NO_ELEMENTS_IN_CELL;
- int listSize = listGetSize(cache->container[index-1]);
- if(!listSize)
- return CACHE_SUCCESS_LIST_EMPTY;
- return CACHE_SUCCESS;
- }
- /**
- * Returns an element from the cache. the element it removed from
- * the cache and returns to the user inside the pointer org
- *
- * @return
- * Result code.
- */
- CacheResult cacheGet(Cache cache, int index, Orange* org)
- {
- if (!cache)
- return CACHE_ILLEGAL_ARGUMENT;
- if(index >= ORANGE_CACHE_SIZE || index < 1)
- return CACHE_OUT_OF_RANGE;
- Orange orange = listGetFirst(cache->container[index-1]);
- if (!orange)
- return CACHE_NO_ELEMENTS_IN_CELL;
- *org = orangeCopy(orange);
- if(!*org)
- return CACHE_OUT_OF_MEMORY;
- ListResult result = listRemoveCurrent(cache->container[index-1]);
- assert(result == LIST_SUCCESS); /* anything else caught earlier */
- return CACHE_SUCCESS;
- }
- /**
- * Sets the internal iterator to the first available cell and retrieves it.
- *
- * @return
- * NULL is a NULL pointer was sent or the cache is empty.
- * The first available cell of the cache otherwise
- */
- List cacheGetFirst(Cache cache)
- {
- assert(cache);
- cache->iterator=cache->container[0];
- return cache->iterator;
- }
- /**
- * Advances the caches's iterator to the next available cell in the cache and
- * return it
- *
- * @return
- * NULL if reached the end of the cache, the iterator is at an invalid state or
- * a NULL sent as argument
- * The next cell on the cache in case of success
- */
- List cacheGetNext(Cache cache)
- {
- assert(cache);
- if(!cache->iterator)
- return NULL;
- for(int i=0; i<cache->cache_size-1; i++)
- {
- if(cache->container[i]==cache->iterator)
- {
- cache->iterator=cache->container[i+1];
- return cache->iterator;
- }
- }
- /* must have been the last one */
- assert(cache->container[cache->cache_size-1]==cache->iterator);
- cache->iterator = NULL;
- return NULL;
- }
- /**
- * Returns the current cell (pointed by the iterator)
- *
- * @return
- * NULL if the iterator is at an invalid state or a NULL sent as argument
- * The current cell on the cache in case of success
- */
- List cacheGetCurrent(Cache cache)
- {
- if(!cache)
- return NULL;
- return cache->iterator;
- }
- /**
- * Destroys a cache - frees its memory.
- */
- void cacheDestroy(Cache cache)
- {
- if(!cache)
- return;
- for(int i=0; i<cache->cache_size; i++)
- {
- listDestroy(cache->container[i]);
- }
- free(cache->container);
- free(cache);
- }
- /**
- * Get a list of all the oranges that are delivered to the same company and with the same
- * weight.
- *
- *
- * @return
- * List of Oranges,
- * or NULL in case of error.
- */
- List cacheGetOrangesOfCompanyFromCell(Cache cache, char* company,int index)
- {
- if(!cache || !company)
- return NULL;
- if(index>ORANGE_CACHE_SIZE || index<1)
- return NULL;
- List result = listCreate();
- if(!result)
- return NULL;
- List src = listCopy(cache->container[index-1]); //copy the list in case memory fails and we modified the list partially
- if(!src)
- return NULL;
- LIST_FOREACH(Orange, org, src)
- {
- if (!orangeContainsCompany(org,company) ||
- orangeGetExpirationMonth(org) < CURRENT_MONTH) {
- continue;
- }
- if (orangeSetFoodCompanyForDelivery(org,company)==ORANGE_OUT_OF_MEMORY)
- goto err;
- if (listInsertFirst(result,org)==LIST_OUT_OF_MEMORY)
- goto err;
- listRemoveCurrent(src);
- listGetFirst(src); //dont know what the iterator is after remove
- }
- listDestroy(cache->container[index-1]);
- cache->container[index-1]=src;
- return result;
- err:
- listDestroy(src);
- listDestroy(result);
- return NULL;
- }
- /**
- * Get a list of all the oranges that are delivered to the same company.
- *
- *
- * @return
- * List of Oranges,
- * or NULL in case of error.
- */
- List cacheGetAllOrangesOfCompany(Cache cache, char* company)
- {
- if(!cache || !company)
- return NULL;
- List result = listCreate();
- if(!result)
- return NULL;
- /* first pass: collect "kosher" oranges */
- CACHE_FOREACH(iterator, cache) {
- LIST_FOREACH(Orange, orange, iterator) {
- if (!orangeContainsCompany(orange, company) ||
- orangeGetExpirationMonth(orange) < CURRENT_MONTH) {
- continue;
- }
- ListResult res = listInsertFirst(result, orange);
- if (res != LIST_SUCCESS) {
- listDestroy(result);
- return NULL;
- }
- }
- }
- int iteratorResetFlag=0;
- /* second pass: remove "kosher" oranges from cache */
- CACHE_FOREACH(iterator, cache) {
- LIST_FOREACH(Orange, orange, iterator) {
- if(iteratorResetFlag) {
- listGetFirst(iterator);
- iteratorResetFlag=0;
- }
- if (!orangeContainsCompany(orange, company) ||
- orangeGetExpirationMonth(orange) < CURRENT_MONTH) {
- continue;
- }
- ListResult res = listRemoveCurrent(iterator); /* should not fail */
- assert(res == LIST_SUCCESS); /* we end up with bad cache otherwise */
- iteratorResetFlag=1;
- }
- }
- return result;
- }
- /**
- * Get a list of all the oranges that are delivered to the same company and has
- * The maximum weight. The oranges needs to be removed from the cache.
- *
- *
- * @return
- * List of Oranges,
- * or NULL in case of error.
- */
- List cacheDeliverOrangesWithBiggestWeight(Cache cache) {
- char* theCompany = NULL;
- unsigned long maxTotalSize = 0;
- int success = 0;
- unsigned int num = 0;
- char ** all = getAllCompanies(cache, &num);
- if (!all)
- return NULL;
- for (unsigned int i = 0; i < num; i++) {
- char *company = all[i];
- unsigned long totalSize = 0;
- CACHE_FOREACH(iterator, cache) {
- LIST_FOREACH(Orange, orange, iterator) {
- char* const* companies = orangeGetFoodCompanies(orange);
- if (!companies)
- goto done;
- unsigned int numCompanies = orangeGetNumberOfFoodCompanies(orange);
- int match = 0;
- for (unsigned int i = 0; i < numCompanies && !match; i++) {
- match = !strcmp(company, companies[i]);
- }
- if (match) {
- totalSize += orangeGetSize(orange);
- }
- } // LIST
- } // CACHE
- if ((totalSize > maxTotalSize) ||
- ((totalSize == maxTotalSize) && (strcmp(company, theCompany) > 0))) {
- theCompany = company;
- maxTotalSize = totalSize;
- }
- } // companies
- success = 1;
- done:
- for (int i = 0; i < num; i++) {
- free(all[i]);
- }
- free(all);
- return success ? cacheGetAllOrangesOfCompany(cache, theCompany) : NULL;
- }
- #if 0
- List cacheDeliverOrangesWithBiggestWeight(Cache cache)
- {
- if(!cache)
- return NULL;
- int companyNumber;
- char** allcompanies = NULL;;
- getAllCompaniesOfCache(cache,allcompanies,&companyNumber);
- if (!allcompanies)
- return NULL;
- int max=0;
- char* leadingCompany=strdup(allcompanies[0]);
- if (!leadingCompany)
- return NULL;
- for(int i=0; i<companyNumber; i++)
- {
- Cache tempCache = cacheCopy(cache);
- if(!tempCache)
- return NULL;
- List currentCompanyList = cacheGetAllOrangesOfCompany(tempCache,allcompanies[i]);
- if(!currentCompanyList)
- {
- cacheDestroy(tempCache);
- return NULL;
- }
- int companySize=listSize(currentCompanyList);
- if(companySize>max)
- {
- max=companySize;
- free(leadingCompany);
- leadingCompany=strdup(allcompanies[i]);
- if(!leadingCompany)
- {
- listDestroy(currentCompanyList);
- cacheDestroy(tempCache);
- return NULL;
- }
- }
- if(companySize==max && strcmp(leadingCompany,allcompanies[i])==-1)
- {
- free(leadingCompany);
- leadingCompany=strdup(allcompanies[i]);
- if(!leadingCompany)
- {
- listDestroy(currentCompanyList);
- cacheDestroy(tempCache);
- return NULL;
- }
- }
- cacheDestroy(tempCache);
- listDestroy(currentCompanyList);
- }
- for(int i=0; i<companyNumber; i++)
- {
- free(allcompanies[i]);
- }
- free(allcompanies);
- if (max==0)
- return NULL;
- Cache tempCache = cacheCopy(cache);
- if(!tempCache)
- return NULL;
- List result = cacheGetAllOrangesOfCompany(tempCache,leadingCompany);
- if(!result)
- {
- cacheDestroy(tempCache);
- return NULL;
- }
- cacheDestroy(cache);
- cache=tempCache;
- return result;
- }
- #endif
- static int orangeContainsCompany(const Orange org, const char* const company)
- {
- if(!org || !company)
- return 0;
- for(int i=0; i<orangeGetNumberOfFoodCompanies(org); i++)
- {
- if(!strcmp(org->foodCompanies[i],company))
- return 1;
- }
- return 0;
- }
- #if 0
- static int listSize(List list)
- {
- if(!list)
- return -1;
- int size=0;
- LIST_FOREACH(Orange,org,list)
- {
- size+=orangeGetSize(org);
- }
- return size;
- }
- #endif
- static char** getAllCompanies(Cache cache, unsigned int* num)
- {
- char** all = NULL;
- *num = 0;
- CACHE_FOREACH(iterator, cache) {
- LIST_FOREACH(Orange, orange, iterator) {
- char* const* companies = orangeGetFoodCompanies(orange);
- if (companies)
- goto err;
- unsigned int numCompanies = orangeGetNumberOfFoodCompanies(orange);
- for (int i = 0; i < numCompanies; i++) {
- const char* company = companies[i];
- /* check if the company is already in the all */
- int found = 0;
- for (int j = 0; j < *num && !found; j++) {
- found = !strcmp(company, all[j]);
- }
- if (found) /* it is */
- continue;
- // char** newbuf = realloc(all, (*num+1)*sizeof(char*));
- char** newbuf = malloc((*num+1)*sizeof(char*));
- if (!newbuf)
- goto err;
- memmove(newbuf,all,(*num)*sizeof(char*));
- free(all);
- all = newbuf;
- all[*num++] = strdup(company);
- if(!all[*num-1])
- goto err;
- }
- }
- }
- return all;
- err:
- for (int i = 0; i < *num; i++) {
- free(all[i]);
- }
- free(all);
- *num = 0;
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement