diff --git a/libretroshare/src/file_sharing/file_sharing_defaults.h b/libretroshare/src/file_sharing/file_sharing_defaults.h index 44b7cfca9..718118c66 100644 --- a/libretroshare/src/file_sharing/file_sharing_defaults.h +++ b/libretroshare/src/file_sharing/file_sharing_defaults.h @@ -53,9 +53,14 @@ static const uint32_t MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE = 23 ; // static const uint32_t MAX_DIR_SYNC_RESPONSE_DATA_SIZE = 20000 ; // Maximum RsItem data size in bytes for serialised directory transmission static const uint32_t DEFAULT_HASH_STORAGE_DURATION_DAYS = 30 ; // remember deleted/inaccessible files for 30 days -static const uint32_t NB_FRIEND_INDEX_BITS = 10 ; // Do not change this! -static const uint32_t NB_ENTRY_INDEX_BITS = 22 ; // Do not change this! -static const uint32_t ENTRY_INDEX_BIT_MASK = 0x003fffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. Depends on the two values just before. Dont change! +static const uint32_t NB_FRIEND_INDEX_BITS_32BITS = 10 ; // Do not change this! +static const uint32_t NB_ENTRY_INDEX_BITS_32BITS = 22 ; // Do not change this! +static const uint32_t ENTRY_INDEX_BIT_MASK_32BITS = 0x003fffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. Depends on the two values just before. Dont change! + +static const uint64_t NB_FRIEND_INDEX_BITS_64BITS = 24 ; // Do not change this! +static const uint64_t NB_ENTRY_INDEX_BITS_64BITS = 40 ; // Do not change this! +static const uint64_t ENTRY_INDEX_BIT_MASK_64BITS = 0x0000000fffffffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. Depends on the two values just before. Dont change! + static const uint32_t DELAY_BEFORE_DROP_REQUEST = 600; // every 10 min static const bool FOLLOW_SYMLINKS_DEFAULT = true; diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 424fe3de8..9fac76483 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -669,10 +669,15 @@ uint32_t p3FileDatabase::locked_getFriendIndex(const RsPeerId& pid) #endif } - if(mRemoteDirectories.size() >= (1 << NB_FRIEND_INDEX_BITS) ) + if(sizeof(void*)==4 && mRemoteDirectories.size() >= (1u << NB_FRIEND_INDEX_BITS_32BITS) ) { - std::cerr << "(EE) FriendIndexTab is full. This is weird. Do you really have more than " << (1<= (1ull << NB_FRIEND_INDEX_BITS_64BITS) ) + { + std::cerr << "(EE) FriendIndexTab is full. This is weird. Do you really have more than " << (1< bool p3FileDatabase::convertPointerToEntryIndex<4>(const void *p, EntryIndex& e, uint32_t& friend_index) { // trust me, I can do this ;-) #pragma GCC diagnostic ignored "-Wstrict-aliasing" - e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK ) ; - friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS ; + e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK_32BITS ) ; + friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS_32BITS ; #pragma GCC diagnostic pop if(friend_index == 0) @@ -718,7 +723,7 @@ bool p3FileDatabase::convertPointerToEntryIndex(const void *p, EntryIndex& e, ui return true; } -bool p3FileDatabase::convertEntryIndexToPointer(const EntryIndex& e, uint32_t fi, void *& p) +template<> bool p3FileDatabase::convertEntryIndexToPointer<4>(const EntryIndex& e, uint32_t fi, void *& p) { // the pointer is formed the following way: // @@ -730,23 +735,69 @@ bool p3FileDatabase::convertEntryIndexToPointer(const EntryIndex& e, uint32_t fi uint32_t fe = (uint32_t)e ; - if(fi+1 >= (1<= (1<< NB_ENTRY_INDEX_BITS)) + if(fi+1 >= (1u<= (1u<< NB_ENTRY_INDEX_BITS_32BITS)) { P3FILELISTS_ERROR() << "(EE) cannot convert entry index " << e << " of friend with index " << fi << " to pointer." << std::endl; return false ; } - p = reinterpret_cast( ( (1+fi) << NB_ENTRY_INDEX_BITS ) + (fe & ENTRY_INDEX_BIT_MASK)) ; + p = reinterpret_cast( ( (1u+fi) << NB_ENTRY_INDEX_BITS_32BITS ) + (fe & ENTRY_INDEX_BIT_MASK_32BITS)) ; return true; } +template<> bool p3FileDatabase::convertPointerToEntryIndex<8>(const void *p, EntryIndex& e, uint32_t& friend_index) +{ + // trust me, I can do this ;-) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK_64BITS ) ; + friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS_64BITS ; +#pragma GCC diagnostic pop + + if(friend_index == 0) + { + std::cerr << "(EE) Cannot find friend index in pointer. Encoded value is zero!" << std::endl; + return false; + } + friend_index--; + +#ifdef DEBUG_P3FILELISTS + std::cerr << "Generated index " << e <<" friend " << friend_index << " from pointer " << p << std::endl; +#endif + return true; +} +template<> bool p3FileDatabase::convertEntryIndexToPointer<8>(const EntryIndex& e, uint32_t fi, void *& p) +{ + // the pointer is formed the following way: + // + // [ 24 bits | 40 bits ] + // + // This means that the whoel software has the following build-in limitation: + // * 1.6M friends + // * 1T shared files. + + uint64_t fe = (uint64_t)e ; + + if(fi+1 >= (1ull<= (1ull<< NB_ENTRY_INDEX_BITS_64BITS)) + { + P3FILELISTS_ERROR() << "(EE) cannot convert entry index " << e << " of friend with index " << fi << " to pointer." << std::endl; + return false ; + } + + p = reinterpret_cast( ( (1ull+fi) << NB_ENTRY_INDEX_BITS_64BITS ) + (fe & ENTRY_INDEX_BIT_MASK_64BITS)) ; + +#ifdef DEBUG_P3FILELISTS + std::cerr << "Generated pointer " << p << " from friend " << fi << " and index " << e << std::endl; +#endif + + return true; +} void p3FileDatabase::requestDirUpdate(void *ref) { uint32_t fi; DirectoryStorage::EntryIndex e ; - convertPointerToEntryIndex(ref,e,fi); + convertPointerToEntryIndex(ref,e,fi); if(fi == 0) return ; // not updating current directory (should we?) @@ -775,13 +826,13 @@ bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result, if(row != 0) return false ; - convertEntryIndexToPointer(0,0,result); + convertEntryIndexToPointer(0,0,result); return true ; } else if((uint32_t)row < mRemoteDirectories.size()) { - convertEntryIndexToPointer(mRemoteDirectories[row]->root(),row+1,result); + convertEntryIndexToPointer(mRemoteDirectories[row]->root(),row+1,result); return true; } else @@ -791,7 +842,7 @@ bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result, uint32_t fi; DirectoryStorage::EntryIndex e ; - convertPointerToEntryIndex(ref,e,fi); + convertPointerToEntryIndex(ref,e,fi); // check consistency if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 0 && (flags & RS_FILE_HINTS_LOCAL))) @@ -806,7 +857,7 @@ bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result, EntryIndex c = 0; bool res = storage->getChildIndex(e,row,c); - convertEntryIndexToPointer(c,fi,result) ; + convertEntryIndexToPointer(c,fi,result) ; return res; } @@ -870,7 +921,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags if(flags & RS_FILE_HINTS_LOCAL) { void *p; - convertEntryIndexToPointer(0,0,p); + convertEntryIndexToPointer(0,0,p); DirStub stub; stub.type = DIR_TYPE_PERSON; @@ -882,7 +933,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags if(mRemoteDirectories[i] != NULL) { void *p; - convertEntryIndexToPointer(mRemoteDirectories[i]->root(),i+1,p); + convertEntryIndexToPointer(mRemoteDirectories[i]->root(),i+1,p); DirStub stub; stub.type = DIR_TYPE_PERSON; @@ -903,7 +954,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags uint32_t fi; DirectoryStorage::EntryIndex e ; - convertPointerToEntryIndex(ref,e,fi); + convertPointerToEntryIndex(ref,e,fi); // check consistency if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 0 && (flags & RS_FILE_HINTS_LOCAL))) @@ -926,10 +977,10 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags // update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert // a pointer into an int. - convertEntryIndexToPointer((intptr_t)d.ref,fi,d.ref) ; + convertEntryIndexToPointer((intptr_t)d.ref,fi,d.ref) ; for(uint32_t i=0;i((intptr_t)d.children[i].ref,fi,d.children[i].ref); if(e == 0) // root { @@ -943,7 +994,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags else d.prow = storage->parentRow(e) ; - convertEntryIndexToPointer((intptr_t)d.parent,fi,d.parent) ; + convertEntryIndexToPointer((intptr_t)d.parent,fi,d.parent) ; } d.id = storage->peerId(); @@ -976,7 +1027,7 @@ uint32_t p3FileDatabase::getType(void *ref) const if(ref == NULL) return DIR_TYPE_ROOT ; - convertPointerToEntryIndex(ref,e,fi); + convertPointerToEntryIndex(ref,e,fi); if(e == 0) return DIR_TYPE_PERSON ; @@ -1056,7 +1107,7 @@ int p3FileDatabase::SearchKeywords(const std::list& keywords, std:: for(std::list::iterator it(firesults.begin());it!=firesults.end();++it) { void *p=NULL; - convertEntryIndexToPointer(*it,0,p); + convertEntryIndexToPointer(*it,0,p); *it = (intptr_t)p ; } } @@ -1080,7 +1131,7 @@ int p3FileDatabase::SearchKeywords(const std::list& keywords, std:: for(std::list::iterator it(local_results.begin());it!=local_results.end();++it) { void *p=NULL; - convertEntryIndexToPointer(*it,i+1,p); + convertEntryIndexToPointer(*it,i+1,p); firesults.push_back((intptr_t)p) ; } } @@ -1114,7 +1165,7 @@ int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::lis for(std::list::iterator it(firesults.begin());it!=firesults.end();++it) { void *p=NULL; - convertEntryIndexToPointer(*it,0,p); + convertEntryIndexToPointer(*it,0,p); *it = (intptr_t)p ; } } @@ -1138,7 +1189,7 @@ int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::lis for(std::list::iterator it(local_results.begin());it!=local_results.end();++it) { void *p=NULL; - convertEntryIndexToPointer(*it,i+1,p); + convertEntryIndexToPointer(*it,i+1,p); firesults.push_back((intptr_t)p) ; } diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h index 13ec0a086..774629b38 100644 --- a/libretroshare/src/file_sharing/p3filelists.h +++ b/libretroshare/src/file_sharing/p3filelists.h @@ -205,8 +205,9 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub // utility functions to make/get a pointer out of an (EntryIndex,PeerId) pair. This is further documented in the .cc - static bool convertEntryIndexToPointer(const EntryIndex &e, uint32_t friend_index, void *& p); - static bool convertPointerToEntryIndex(const void *p, EntryIndex& e, uint32_t& friend_index) ; + template static bool convertEntryIndexToPointer(const EntryIndex &e, uint32_t friend_index, void *& p); + template static bool convertPointerToEntryIndex(const void *p, EntryIndex& e, uint32_t& friend_index) ; + uint32_t locked_getFriendIndex(const RsPeerId& pid); void handleDirSyncRequest (RsFileListsSyncRequestItem *) ;