/**************************************************************************
 * public functions
 **************************************************************************/
int
initPreload (preloadConfig_t *preloadConfig, rodsEnv *myPreloadRodsEnv, rodsArguments_t *myPreloadRodsArgs) {
    rodsLog (LOG_DEBUG, "initPreload: MyPreloadConfig.preload = %d", preloadConfig->preload);
    rodsLog (LOG_DEBUG, "initPreload: MyPreloadConfig.clearCache = %d", preloadConfig->clearCache);
    rodsLog (LOG_DEBUG, "initPreload: MyPreloadConfig.cachePath = %s", preloadConfig->cachePath);
    rodsLog (LOG_DEBUG, "initPreload: MyPreloadConfig.cacheMaxSize = %lld", preloadConfig->cacheMaxSize);
    rodsLog (LOG_DEBUG, "initPreload: MyPreloadConfig.preloadMinSize = %lld", preloadConfig->preloadMinSize);

    // copy given configuration
    memcpy(&PreloadConfig, preloadConfig, sizeof(preloadConfig_t));
    PreloadRodsEnv = myPreloadRodsEnv;
    PreloadRodsArgs = myPreloadRodsArgs;

    // init hashtables
    PreloadThreadTable = newHashTable(NUM_PRELOAD_THREAD_HASH_SLOT);
    PreloadFileHandleTable = newHashTable(NUM_PRELOAD_FILEHANDLE_HASH_SLOT);

    // init lists
    PreloadThreadList = newConcurrentList();

    // init lock
    INIT_LOCK(PreloadLock);

    _preparePreloadCacheDir(preloadConfig->cachePath);

    if(preloadConfig->clearCache) {
        // clear all cache
        _removeAllCaches();
    } else {
        // remove incomplete preload caches
        _removeAllIncompleteCaches(preloadConfig->cachePath);
    }

    return (0);
}
int
uninitPreload (preloadConfig_t *preloadConfig) {
    int status;
    int i;
    int size;

    // destroy preload thread list
    size = listSize(PreloadThreadList);
    for(i=0;i<size;i++) {
        preloadThreadInfo_t *threadInfo = (preloadThreadInfo_t *)removeFirstElementOfConcurrentList(PreloadThreadList);
        if(threadInfo->running == PRELOAD_THREAD_RUNNING) {        
#ifdef USE_BOOST
            status = threadInfo->thread->join();
#else
            status = pthread_join(threadInfo->thread, NULL);
#endif
        }

        if(threadInfo->path != NULL) {
            free(threadInfo->path);
            threadInfo->path = NULL;
        }
    }

    if(preloadConfig->clearCache) {
        // clear all cache
        _removeAllCaches();
    } else {
        // remove incomplete preload caches
        _removeAllIncompleteCaches(preloadConfig->cachePath);
    }

    FREE_LOCK(PreloadLock);
    return (0);
}
int
uninitPreload (preloadConfig_t *preloadConfig) {
    if(preloadConfig->clearCache) {
        // clear all cache
        _removeAllCaches();
    } else {
        // remove incomplete preload caches
        _removeAllIncompleteCaches();
    }

    FREE_LOCK(PreloadLock);
    return (0);
}