// Single-level arraytemplate<int BITS>classTCMalloc_PageMap1{private:staticconstint LENGTH =1<< BITS;void**array_;public:typedef uintptr_t Number;explicitTCMalloc_PageMap1(void*(*allocator)(size_t)){array_ =reinterpret_cast<void**>((*allocator)(sizeof(void*)<< BITS));memset(array_,0,sizeof(void*)<< BITS);}// Return the current value for KEY. Returns NULL if not yet set,// or if k is out of range.void*get(Number k)const{if((k >> BITS)>0){returnNULL;}return array_[k];}// REQUIRES "k" is in range "[0,2^BITS-1]".// REQUIRES "k" has been ensured before.// Sets the value 'v' for key 'k'.voidset(Number k,void*v){array_[k]= v;}};// Two-level radix treetemplate<int BITS>classTCMalloc_PageMap2{private:// Put 32 entries in the root and (2^BITS)/32 entries in each leaf.staticconstint ROOT_BITS =5;staticconstint ROOT_LENGTH =1<< ROOT_BITS;staticconstint LEAF_BITS = BITS - ROOT_BITS;staticconstint LEAF_LENGTH =1<< LEAF_BITS;// Leaf nodestructLeaf{void*values[LEAF_LENGTH];};Leaf *root_[ROOT_LENGTH];// Pointers to 32 child nodesvoid*(*allocator_)(size_t);// Memory allocatorpublic:typedef uintptr_t Number;explicitTCMalloc_PageMap2(void*(*allocator)(size_t)){allocator_ = allocator;memset(root_,0,sizeof(root_));}void*get(Number k)const{const Number i1 = k >> LEAF_BITS;const Number i2 = k &(LEAF_LENGTH -1);if((k >> BITS)>0|| root_[i1]==NULL){returnNULL;}return root_[i1]->values[i2];}voidset(Number k,void*v){const Number i1 = k >> LEAF_BITS;const Number i2 = k &(LEAF_LENGTH -1);ASSERT(i1 < ROOT_LENGTH);root_[i1]->values[i2]= v;}boolEnsure(Number start, size_t n){for(Number key = start; key <= start + n -1;){const Number i1 = key >> LEAF_BITS;// Check for overflowif(i1 >= ROOT_LENGTH)returnfalse;// Make 2nd level node if necessaryif(root_[i1]==NULL){Leaf *leaf =reinterpret_cast<Leaf *>((*allocator_)(sizeof(Leaf)));if(leaf ==NULL)returnfalse;memset(leaf,0,sizeof(*leaf));root_[i1]= leaf;}// Advance key past whatever is covered by this leaf nodekey =((key >> LEAF_BITS)+1)<< LEAF_BITS;}returntrue;}voidPreallocateMoreMemory(){// Allocate enough to keep track of all possible pagesEnsure(0,1<< BITS);}};// Three-level radix treetemplate<int BITS>classTCMalloc_PageMap3{private:// How many bits should we consume at each interior levelstaticconstint INTERIOR_BITS =(BITS +2)/3;// Round-upstaticconstint INTERIOR_LENGTH =1<< INTERIOR_BITS;// How many bits should we consume at leaf levelstaticconstint LEAF_BITS = BITS -2* INTERIOR_BITS;staticconstint LEAF_LENGTH =1<< LEAF_BITS;// Interior nodestructNode{Node *ptrs[INTERIOR_LENGTH];};// Leaf nodestructLeaf{void*values[LEAF_LENGTH];};Node *root_;// Root of radix treevoid*(*allocator_)(size_t);// Memory allocatorNode *NewNode(){Node *result =reinterpret_cast<Node *>((*allocator_)(sizeof(Node)));if(result !=NULL){memset(result,0,sizeof(*result));}return result;}public:typedef uintptr_t Number;explicitTCMalloc_PageMap3(void*(*allocator)(size_t)){allocator_ = allocator;root_ =NewNode();}void*get(Number k)const{const Number i1 = k >>(LEAF_BITS + INTERIOR_BITS);const Number i2 =(k >> LEAF_BITS)&(INTERIOR_LENGTH -1);const Number i3 = k &(LEAF_LENGTH -1);if((k >> BITS)>0||root_->ptrs[i1]==NULL|| root_->ptrs[i1]->ptrs[i2]==NULL){returnNULL;}returnreinterpret_cast<Leaf *>(root_->ptrs[i1]->ptrs[i2])->values[i3];}voidset(Number k,void*v){ASSERT(k >> BITS ==0);const Number i1 = k >>(LEAF_BITS + INTERIOR_BITS);const Number i2 =(k >> LEAF_BITS)&(INTERIOR_LENGTH -1);const Number i3 = k &(LEAF_LENGTH -1);reinterpret_cast<Leaf *>(root_->ptrs[i1]->ptrs[i2])->values[i3]= v;}boolEnsure(Number start, size_t n){for(Number key = start; key <= start + n -1;){const Number i1 = key >>(LEAF_BITS + INTERIOR_BITS);const Number i2 =(key >> LEAF_BITS)&(INTERIOR_LENGTH -1);// Check for overflowif(i1 >= INTERIOR_LENGTH || i2 >= INTERIOR_LENGTH)returnfalse;// Make 2nd level node if necessaryif(root_->ptrs[i1]==NULL){Node *n =NewNode();if(n ==NULL)returnfalse;root_->ptrs[i1]= n;}// Make leaf node if necessaryif(root_->ptrs[i1]->ptrs[i2]==NULL){Leaf *leaf =reinterpret_cast<Leaf *>((*allocator_)(sizeof(Leaf)));if(leaf ==NULL)returnfalse;memset(leaf,0,sizeof(*leaf));root_->ptrs[i1]->ptrs[i2]=reinterpret_cast<Node *>(leaf);}// Advance key past whatever is covered by this leaf nodekey =((key >> LEAF_BITS)+1)<< LEAF_BITS;}returntrue;}voidPreallocateMoreMemory(){}};