/* */ #ifndef _D_BITFIELD_MAN_H_ #define _D_BITFIELD_MAN_H_ #include "common.h" #include "Randomizer.h" #include typedef deque BlockIndexes; class BitfieldMan { private: uint32_t blockLength; uint64_t totalLength; unsigned char* bitfield; unsigned char* useBitfield; unsigned char* filterBitfield; uint32_t bitfieldLength; uint32_t blocks; bool filterEnabled; RandomizerHandle randomizer; // for caching uint32_t cachedNumMissingBlock; uint32_t cachedNumFilteredBlock; uint64_t cachedCompletedLength; uint64_t cachedFilteredComletedLength; uint64_t cachedFilteredTotalLength; uint32_t countSetBit(const unsigned char* bitfield, uint32_t len) const; int32_t getNthBitIndex(const unsigned char bit, uint32_t nth) const; int32_t getMissingIndexRandomly(const unsigned char* bitfield, uint32_t len) const; bool isBitSetInternal(const unsigned char* bitfield, int32_t index) const; bool setBitInternal(unsigned char* bitfield, int32_t index, bool on); bool setFilterBit(int32_t index); int32_t getStartIndex(int32_t index) const; int32_t getEndIndex(int32_t index) const; uint64_t getCompletedLength(bool useFilter) const; public: BitfieldMan(uint32_t blockLength, uint64_t totalLength); BitfieldMan(const BitfieldMan& bitfieldMan); ~BitfieldMan(); BitfieldMan& operator=(const BitfieldMan& bitfieldMan) { if(this != &bitfieldMan) { blockLength = bitfieldMan.blockLength; totalLength = bitfieldMan.totalLength; blocks = bitfieldMan.blocks; bitfieldLength = bitfieldMan.bitfieldLength; filterEnabled = bitfieldMan.filterEnabled; delete [] bitfield; bitfield = new unsigned char[bitfieldLength]; memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength); delete [] useBitfield; useBitfield = new unsigned char[bitfieldLength]; memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength); delete [] filterBitfield; if(filterEnabled) { filterBitfield = new unsigned char[bitfieldLength]; memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength); } else { filterBitfield = 0; } updateCache(); } return *this; } uint32_t getBlockLength() const { return blockLength; } uint32_t getLastBlockLength() const { return totalLength-blockLength*(blocks-1); } uint32_t getBlockLength(int32_t index) const { if(index == (int32_t)(blocks-1)) { return getLastBlockLength(); } else if(0 <= index && index < (int32_t)(blocks-1)) { return getBlockLength(); } else { return 0; } } uint64_t getTotalLength() const { return totalLength; } /** * affected by filter */ bool hasMissingPiece(const unsigned char* bitfield, uint32_t len) const; /** * affected by filter */ int32_t getMissingIndex(const unsigned char* bitfield, uint32_t len) const; /** * affected by filter */ int32_t getMissingIndex() const; /** * affected by filter */ int32_t getFirstMissingUnusedIndex(const unsigned char* bitfield, uint32_t len) const; /** * affected by filter */ int32_t getFirstMissingUnusedIndex() const; /** * affected by filter */ int32_t getMissingUnusedIndex(const unsigned char* bitfield, uint32_t len) const; /** * affected by filter */ int32_t getMissingUnusedIndex() const; /** * affected by filter */ int32_t getSparseMissingUnusedIndex() const; /** * affected by filter */ BlockIndexes getAllMissingIndexes() const; /** * affected by filter */ BlockIndexes getAllMissingIndexes(const unsigned char* bitfield, uint32_t len) const; /** * affected by filter */ uint32_t countMissingBlock() const; /** * affected by filter */ uint32_t countMissingBlockNow() const; bool setUseBit(int32_t index); bool unsetUseBit(int32_t index); bool setBit(int32_t index); bool unsetBit(int32_t index); bool isBitSet(int32_t index) const; bool isUseBitSet(int32_t index) const; /** * affected by filter */ bool isAllBitSet() const; const unsigned char* getBitfield() const { return bitfield; } uint32_t getBitfieldLength() const { return bitfieldLength; } /** * affected by filter */ uint32_t countBlock() const; /** * affected by filter */ uint32_t countFilteredBlockNow() const; int32_t getMaxIndex() const { return blocks-1; } void setBitfield(const unsigned char* bitfield, uint32_t bitfieldLength); void clearAllBit(); void setAllBit(); void clearAllUseBit(); void setAllUseBit(); void addFilter(int64_t offset, uint64_t length); /** * Clears filter and disables filter */ void clearFilter(); void enableFilter(); void disableFilter(); bool isFilterEnabled() const; /** * affected by filter */ uint64_t getFilteredTotalLength() const; /** * affected by filter */ uint64_t getFilteredTotalLengthNow() const; uint64_t getCompletedLength() const; uint64_t getCompletedLengthNow() const; /** * affected by filter */ uint64_t getFilteredCompletedLength() const; /** * affected by filter */ uint64_t getFilteredCompletedLengthNow() const; void setRandomizer(const RandomizerHandle& randomizer) { this->randomizer = randomizer; } RandomizerHandle getRandomizer() const { return randomizer; } void updateCache(); bool isBitRangeSet(int32_t startIndex, int32_t endIndex) const; void unsetBitRange(int32_t startIndex, int32_t endIndex); }; #endif // _D_BITFIELD_MAN_H_