                     size_t pMaxBinSize, size_t pMinimalBlocksInCommon,
                     size_t pExcessFactor, size_t pMaximalNumberOfHashCollisions, size_t pBloomierFilter,
                     int pPruneInverseIndex, float pPruneInverseIndexAfterInstance, int pRemoveHashFunctionWithLessEntriesAs,
-                    size_t pHashAlgorithm, size_t pBlockSize, size_t pShingle, size_t pRemoveValueWithLeastSigificantBit) {   
+                    size_t pHashAlgorithm, size_t pBlockSize, size_t pShingle, size_t pRemoveValueWithLeastSigificantBit):InverseIndex() {   
         // std::cout << __LINE__ << std::endl;
                         
     mNumberOfHashFunctions = pNumberOfHashFunctions;

    mPruneInverseIndexAfterInstance = pPruneInverseIndexAfterInstance;
    mRemoveHashFunctionWithLessEntriesAs = pRemoveHashFunctionWithLessEntriesAs;
    mHashAlgorithm = pHashAlgorithm;
    // mSignatureStorage = new umap_uniqueElement();
    // mHash = new Hash();
    mBlockSize = pBlockSize;
    mShingle = pShingle;
    size_t maximalFeatures = 5000;
    size_t inverseIndexSize;
    if (mShingle == 0) {
        if (mBlockSize == 0) {

umap_uniqueElement* InverseIndexCuda::computeSignatureMap(const SparseMatrixFloat* pRawData) {
}
void InverseIndexCuda::fit(const SparseMatrixFloat* pRawData) {
    printf("foo");
    int maxBlocks = 65535;
    printf("number of hash functions: %i", mNumberOfHashFunctions);
    if (mNumberOfHashFunctions % 32 != 0) {
        mNumberOfHashFunctions += 32 - (mNumberOfHashFunctions % 32);
    }
    printf("number of hash functions: %i", mNumberOfHashFunctions);
    
    cudaMalloc((void **) &mDev_FeatureList,
               pRawData->getMaxNnz() * pRawData->getNumberOfInstances() * sizeof(size_t));
    cudaMalloc((void **) &mDev_SizeOfInstanceList,
               pRawData->getNumberOfInstances() * sizeof(size_t));
    cudaMalloc((void **) &mDev_ComputedSignaturesPerInstance,
               pRawData->getNumberOfInstances()* mNumberOfHashFunctions * sizeof(size_t));
    cudaMemcpy(mDev_FeatureList, pRawData->getSparseMatrixIndex(),
                pRawData->getMaxNnz() * pRawData->getNumberOfInstances() * sizeof(size_t),
               cudaMemcpyHostToDevice);
    cudaMemcpy(mDev_SizeOfInstanceList, pRawData->getSparseMatrixSizeOfInstances(),
            pRawData->getNumberOfInstances() * sizeof(size_t),
            cudaMemcpyHostToDevice);
    
    // fitGpu<<<pRawData->getNumberOfInstances(), mNumberOfHashFunctions, mNumberOfHashFunctions>>>
   
    fitCuda<<<128, 128, mNumberOfHashFunctions>>>
    (mDev_FeatureList, 
    mDev_SizeOfInstanceList, 
    mNumberOfHashFunctions, 
    pRawData->getMaxNnz(),
            mDev_ComputedSignaturesPerInstance, 
            pRawData->getNumberOfInstances());
    size_t* instancesHashValues = (size_t*) malloc(pRawData->getNumberOfInstances() * mNumberOfHashFunctions * sizeof(size_t));
    cudaMemcpy(instancesHashValues, mDev_ComputedSignaturesPerInstance, 
                pRawData->getNumberOfInstances() * mNumberOfHashFunctions * sizeof(size_t),
                cudaMemcpyDeviceToHost);
   for(size_t i = 0; i < pRawData->getNumberOfInstances(); ++i) {
       printf("Instance: %i of %i", i, pRawData->getNumberOfInstances());
       for (size_t j = 0; j < mNumberOfHashFunctions; ++j) {
           printf("%i,", instancesHashValues[i*mNumberOfHashFunctions + j]);
       }
       printf("\n");
   }
   free(instancesHashValues);
}

neighborhood* InverseIndexCuda::kneighbors(const umap_uniqueElement* pSignaturesMap, 
