double Nonleaf::ClosestDiffTwo(Stat *Stats, int &i, int &j) const { Entry tmpent; tmpent.Init(Stats->Dimension); int i1,j1,imin,jmin; double d, dmin; if (actsize<2) print_error("Nonleaf::ClosestDiffTwo","Less than 2 entries"); if (actsize==2) { d=distance(Stats->GDtype,entry[0],entry[1]); if (d==0) print_error("Nonleaf::ClosestDiffTwo", "Same 2 entries in a nonleaf: should not happen"); } dmin=HUGE_DOUBLE; imin=0; jmin=1; for (i1=0;i1<actsize-1;i1++) for (j1=i1+1;j1<actsize;j1++) { d = distance(Stats->GDtype,entry[i1],entry[j1]); if (d>0 && d<dmin) { imin = i1; jmin = j1; dmin = d;} } i=imin; j=jmin; tmpent.Add(entry[i],entry[j]); return tmpent.Fitness(Stats->Ftype); }
static status_t Create(Entry* parent, const char* name, bool implicit, Entry*& _entry) { char* clonedName = strdup(name); if (clonedName == NULL) return B_NO_MEMORY; Entry* entry = new(std::nothrow) Entry(parent, clonedName, implicit); if (entry == NULL) { free(clonedName); return B_NO_MEMORY; } status_t error = entry->Init(); if (error != B_OK) { delete entry; return error; } if (parent != NULL) parent->fChildren.Insert(entry); _entry = entry; return B_OK; }
Node* Nonleaf::AdjustTree(Stat *Stats, const Entry &ent) { int EntryI; int i,j; double d; Node *ResNode, *NewNode; Entry ResEnt; ResEnt.Init(Stats->Dimension); EntryI=ClosestOne(Stats,ent); ResNode=child[EntryI]->AdjustTree(Stats,ent); if (ResNode!=NULL) { // Split Propagate child[EntryI]->CF(entry[EntryI]); ResNode->CF(ResEnt); NewNode=InsertMightSplit(Stats,ResEnt,ResNode); if (NewNode==NULL) { // Split Propagate Stops if (actsize>2) { d=ClosestTwo(Stats, i, j); if (!(i==EntryI&&j==actsize-1)) MergeMightResplit(Stats, i, j); } return NULL; } else { if (this!=Stats->OldRoot) return NewNode; else { // Create New Root Stats->CreateNewRoot(this,NewNode); return NULL; } } } else { // No Split Coming Up entry[EntryI]+=ent; return NULL; } }
void Node::Print_Summary(Stat *Stats, std::ofstream &fo) const { Entry tmpent; tmpent.Init(entry[0].sx.dim); CF(tmpent); fo<<"Root CF\t"<<tmpent<<std::endl; fo<<"FootPrint\t"<<sqrt(tmpent.Radius())<<std::endl; #ifdef RECTANGLE Rectangle tmprect; tmprect.Init(entry[0].sx.dim); Rect(tmprect); fo<<"Root Rectangle\t"<<tmprect<<std::endl; #endif RECTANGLE fo<<"Leaf Nodes\t"<<LeafNum()<<std::endl; fo<<"Nonleaf Nodes\t"<<NonleafNum()<<std::endl; fo<<"Tree Size\t"<<Size()<<std::endl; fo<<"Tree Depth\t"<<Depth()<<std::endl; fo<<"Leaf Entries\t"<<NumLeafEntry()<<std::endl; fo<<"Nonleaf Entries\t"<<NumNonleafEntry()<<std::endl; fo<<"Occupancy\t"<<Occupancy(Stats)<<std::endl; }
Result OCSPCache::Put(const CertID& aCertID, Result aResult, Time aThisUpdate, Time aValidThrough) { MutexAutoLock lock(mMutex); size_t index; if (FindInternal(aCertID, index, lock)) { // Never replace an entry indicating a revoked certificate. if (mEntries[index]->mResult == Result::ERROR_REVOKED_CERTIFICATE) { LogWithCertID("OCSPCache::Put(%p) already in cache as revoked - " "not replacing", aCertID); MakeMostRecentlyUsed(index, lock); return Success; } // Never replace a newer entry with an older one unless the older entry // indicates a revoked certificate, which we want to remember. if (mEntries[index]->mThisUpdate > aThisUpdate && aResult != Result::ERROR_REVOKED_CERTIFICATE) { LogWithCertID("OCSPCache::Put(%p) already in cache with more recent " "validity - not replacing", aCertID); MakeMostRecentlyUsed(index, lock); return Success; } // Only known good responses or responses indicating an unknown // or revoked certificate should replace previously known responses. if (aResult != Success && aResult != Result::ERROR_OCSP_UNKNOWN_CERT && aResult != Result::ERROR_REVOKED_CERTIFICATE) { LogWithCertID("OCSPCache::Put(%p) already in cache - not replacing " "with less important status", aCertID); MakeMostRecentlyUsed(index, lock); return Success; } LogWithCertID("OCSPCache::Put(%p) already in cache - replacing", aCertID); mEntries[index]->mResult = aResult; mEntries[index]->mThisUpdate = aThisUpdate; mEntries[index]->mValidThrough = aValidThrough; MakeMostRecentlyUsed(index, lock); return Success; } if (mEntries.length() == MaxEntries) { LogWithCertID("OCSPCache::Put(%p) too full - evicting an entry", aCertID); for (Entry** toEvict = mEntries.begin(); toEvict != mEntries.end(); toEvict++) { // Never evict an entry that indicates a revoked or unknokwn certificate, // because revoked responses are more security-critical to remember. if ((*toEvict)->mResult != Result::ERROR_REVOKED_CERTIFICATE && (*toEvict)->mResult != Result::ERROR_OCSP_UNKNOWN_CERT) { delete *toEvict; mEntries.erase(toEvict); break; } } // Well, we tried, but apparently everything is revoked or unknown. // We don't want to remove a cached revoked or unknown response. If we're // trying to insert a good response, we can just return "successfully" // without doing so. This means we'll lose some speed, but it's not a // security issue. If we're trying to insert a revoked or unknown response, // we can't. We should return with an error that causes the current // verification to fail. if (mEntries.length() == MaxEntries) { return aResult; } } Entry* newEntry = new (std::nothrow) Entry(aResult, aThisUpdate, aValidThrough); // Normally we don't have to do this in Gecko, because OOM is fatal. // However, if we want to embed this in another project, OOM might not // be fatal, so handle this case. if (!newEntry) { return Result::FATAL_ERROR_NO_MEMORY; } Result rv = newEntry->Init(aCertID); if (rv != Success) { delete newEntry; return rv; } if (!mEntries.append(newEntry)) { delete newEntry; return Result::FATAL_ERROR_NO_MEMORY; } LogWithCertID("OCSPCache::Put(%p) added to cache", aCertID); return Success; }
double Node::Fitness(short ftype) const { Entry tmpent; tmpent.Init(entry[0].sx.dim); this->CF(tmpent); return tmpent.Fitness(ftype); }
double Node::Diameter() const { Entry tmpent; tmpent.Init(entry[0].sx.dim); this->CF(tmpent); return tmpent.Diameter(); }
double Node::Radius() const { Entry tmpent; tmpent.Init(entry[0].sx.dim); this->CF(tmpent); return tmpent.Radius(); }
void Hierarchy0(int &n, // final number of clusters const int K, // final number of clusters Entry **entries, short GDtype, short Ftype, double Ft) { if (n<=1) return; int i, j, imin, jmin, done; short *checked = new short[n]; memset(checked,0,n*sizeof(short)); // 0: unchecked; // -1: exceeds the given threshold if merged with nearest neighbor; // -2: nonexistant after merging. double *dist = new double[n*(n-1)/2]; double d, dmin; Entry tmpent; tmpent.Init((*entries)[0].sx.dim); dmin = HUGE; // compute all initial distances and closest pair for (i=0; i<n-1; i++) for (j=i+1; j<n; j++) { d = distance(GDtype,(*entries)[i],(*entries)[j]); dist[i*n-i*(i+1)/2+j-i-1] = d; if (d<dmin) { dmin = d; imin = i; jmin = j; } } if (K==0) {// ****** case 1 ****** cluster by threshold ft done = FALSE; while (done==FALSE) { tmpent.Add((*entries)[imin],(*entries)[jmin]); if (tmpent.Fitness(Ftype) < Ft) { // within the threshold (*entries)[imin] += (*entries)[jmin]; checked[jmin] = -2; for (i=0; i<imin; i++) { if (checked[i]==0) { dist[i*n-i*(i+1)/2+imin-i-1] = distance(GDtype,(*entries)[i],(*entries)[imin]); }} for (j=imin+1; j<n; j++) { if (checked[j]==0) { dist[imin*n-imin*(imin+1)/2+j-imin-1] = distance(GDtype,(*entries)[imin],(*entries)[j]); }} } else { // exceeds the threshold checked[imin] = -1; checked[jmin] = -1; } done = TRUE; dmin = HUGE; for (i=0; i<n-1; i++) { if (checked[i]==0) { for (j=i+1; j<n; j++) { if (checked[j]==0) { d = dist[i*n-i*(i+1)/2+j-i-1]; if (d<dmin) { done = FALSE; dmin = d; imin = i; jmin = j; }}}}} } // end of while } // end of if else { // ***** case 2 ***** cluster by number k done = n; while (done > K) { (*entries)[imin] += (*entries)[jmin]; checked[jmin] = -2; done--; for (i=0; i<imin; i++) { if (checked[i]==0) { dist[i*n-i*(i+1)/2+imin-i-1] = distance(GDtype,(*entries)[i],(*entries)[imin]); }} for (j=imin+1; j<n; j++) { if (checked[j]==0) { dist[imin*n-imin*(imin+1)/2+j-imin-1] = distance(GDtype,(*entries)[imin],(*entries)[j]); }} dmin = HUGE; for (i=0; i<n-1; i++) { if (checked[i]==0) { for (j=i+1; j<n; j++) { if (checked[j]==0) { d = dist[i*n-i*(i+1)/2+j-i-1]; if (d<dmin) { dmin = d; imin = i; jmin = j; }}}}} } // end of while } // end of else j = 0; for (i=0; i<n; i++) if (checked[i]!=-2) { (*entries)[j]=(*entries)[i]; j++; } n=j; delete [] checked; delete [] dist; }