BitfieldMan.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2006 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #include "BitfieldMan.h"
  36. #include "Util.h"
  37. #include <string.h>
  38. BitfieldMan::BitfieldMan(int32_t blockLength, int64_t totalLength)
  39. :blockLength(blockLength),
  40. totalLength(totalLength),
  41. bitfield(0),
  42. useBitfield(0),
  43. filterBitfield(0),
  44. bitfieldLength(0),
  45. blocks(0),
  46. filterEnabled(false),
  47. randomizer(0),
  48. cachedNumMissingBlock(0),
  49. cachedNumFilteredBlock(0),
  50. cachedCompletedLength(0),
  51. cachedFilteredComletedLength(0),
  52. cachedFilteredTotalLength(0)
  53. {
  54. if(blockLength > 0 && totalLength > 0) {
  55. blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0);
  56. bitfieldLength = blocks/8+(blocks%8 ? 1 : 0);
  57. bitfield = new unsigned char[bitfieldLength];
  58. useBitfield = new unsigned char[bitfieldLength];
  59. memset(bitfield, 0, bitfieldLength);
  60. memset(useBitfield, 0, bitfieldLength);
  61. updateCache();
  62. }
  63. }
  64. BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan)
  65. :blockLength(0),
  66. totalLength(0),
  67. bitfield(0),
  68. useBitfield(0),
  69. filterBitfield(0),
  70. bitfieldLength(0),
  71. blocks(0),
  72. filterEnabled(false),
  73. randomizer(0),
  74. cachedNumMissingBlock(0),
  75. cachedNumFilteredBlock(0),
  76. cachedCompletedLength(0),
  77. cachedFilteredComletedLength(0),
  78. cachedFilteredTotalLength(0)
  79. {
  80. blockLength = bitfieldMan.blockLength;
  81. totalLength = bitfieldMan.totalLength;
  82. blocks = bitfieldMan.blocks;
  83. bitfieldLength = bitfieldMan.bitfieldLength;
  84. bitfield = new unsigned char[bitfieldLength];
  85. useBitfield = new unsigned char[bitfieldLength];
  86. memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
  87. memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
  88. filterEnabled = bitfieldMan.filterEnabled;
  89. if(filterBitfield) {
  90. filterBitfield = new unsigned char[bitfieldLength];
  91. memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
  92. } else {
  93. filterBitfield = 0;
  94. }
  95. this->randomizer = bitfieldMan.randomizer;
  96. updateCache();
  97. }
  98. BitfieldMan::~BitfieldMan() {
  99. delete [] bitfield;
  100. delete [] useBitfield;
  101. delete [] filterBitfield;
  102. }
  103. int32_t BitfieldMan::countSetBit(const unsigned char* bitfield, int32_t len) const {
  104. int32_t count = 0;
  105. int32_t size = sizeof(int32_t);
  106. for(int32_t i = 0; i < len/size; ++i) {
  107. count += Util::countBit(*(uint32_t*)&bitfield[i*size]);
  108. }
  109. for(int32_t i = len-len%size; i < len; i++) {
  110. count += Util::countBit((uint32_t)bitfield[i]);
  111. }
  112. return count;
  113. }
  114. int32_t BitfieldMan::getNthBitIndex(const unsigned char bitfield, int32_t nth) const {
  115. int32_t index = -1;
  116. for(int bs = 7; bs >= 0; bs--) {
  117. unsigned char mask = 1 << bs;
  118. if(bitfield & mask) {
  119. nth--;
  120. if(nth == 0) {
  121. index = 7-bs;
  122. break;
  123. }
  124. }
  125. }
  126. return index;
  127. }
  128. int32_t
  129. BitfieldMan::getMissingIndexRandomly(const unsigned char* bitfield,
  130. int32_t bitfieldLength) const
  131. {
  132. int32_t byte = (int32_t)(((double)bitfieldLength)*
  133. randomizer->getRandomNumber()/
  134. (randomizer->getMaxRandomNumber()+1.0));
  135. unsigned char lastMask = 0;
  136. // the number of bytes in the last byte of bitfield
  137. int32_t lastByteLength = totalLength%(blockLength*8);
  138. // the number of block in the last byte of bitfield
  139. int32_t lastBlockCount = DIV_FLOOR(lastByteLength, blockLength);
  140. for(int32_t i = 0; i < lastBlockCount; ++i) {
  141. lastMask >>= 1;
  142. lastMask |= 0x80;
  143. }
  144. for(int32_t i = 0; i < bitfieldLength; ++i) {
  145. unsigned char mask;
  146. if(byte == bitfieldLength-1) {
  147. mask = lastMask;
  148. } else {
  149. mask = 0xff;
  150. }
  151. if(bitfield[byte]&mask) {
  152. int32_t index = byte*8+getNthBitIndex(bitfield[byte], 1);
  153. return index;
  154. }
  155. byte++;
  156. if(byte == bitfieldLength) {
  157. byte = 0;
  158. }
  159. }
  160. return -1;
  161. }
  162. bool BitfieldMan::hasMissingPiece(const unsigned char* peerBitfield, int32_t length) const {
  163. if(bitfieldLength != length) {
  164. return false;
  165. }
  166. bool retval = false;
  167. for(int32_t i = 0; i < bitfieldLength; ++i) {
  168. unsigned char temp = peerBitfield[i] & ~bitfield[i];
  169. if(filterEnabled) {
  170. temp &= filterBitfield[i];
  171. }
  172. if(temp&0xff) {
  173. retval = true;
  174. break;
  175. }
  176. }
  177. return retval;
  178. }
  179. int32_t BitfieldMan::getMissingIndex(const unsigned char* peerBitfield, int32_t length) const {
  180. if(bitfieldLength != length) {
  181. return -1;
  182. }
  183. unsigned char* tempBitfield = new unsigned char[bitfieldLength];
  184. for(int32_t i = 0; i < bitfieldLength; ++i) {
  185. tempBitfield[i] = peerBitfield[i] & ~bitfield[i];
  186. if(filterEnabled) {
  187. tempBitfield[i] &= filterBitfield[i];
  188. }
  189. }
  190. int32_t index = getMissingIndexRandomly(tempBitfield, bitfieldLength);
  191. delete [] tempBitfield;
  192. return index;
  193. }
  194. int32_t BitfieldMan::getMissingUnusedIndex(const unsigned char* peerBitfield, int32_t length) const {
  195. if(bitfieldLength != length) {
  196. return -1;
  197. }
  198. unsigned char* tempBitfield = new unsigned char[bitfieldLength];
  199. for(int32_t i = 0; i < bitfieldLength; ++i) {
  200. tempBitfield[i] = peerBitfield[i] & ~bitfield[i] & ~useBitfield[i];
  201. if(filterEnabled) {
  202. tempBitfield[i] &= filterBitfield[i];
  203. }
  204. }
  205. int32_t index = getMissingIndexRandomly(tempBitfield, bitfieldLength);
  206. delete [] tempBitfield;
  207. return index;
  208. }
  209. int32_t BitfieldMan::getFirstMissingUnusedIndex(const unsigned char* peerBitfield, int32_t length) const {
  210. if(bitfieldLength != length) {
  211. return -1;
  212. }
  213. for(int32_t i = 0; i < bitfieldLength; ++i) {
  214. unsigned char bit = peerBitfield[i] & ~bitfield[i] & ~useBitfield[i];
  215. if(filterEnabled) {
  216. bit &= filterBitfield[i];
  217. }
  218. for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
  219. unsigned char mask = 1 << bs;
  220. if(bit & mask) {
  221. return i*8+7-bs;
  222. }
  223. }
  224. }
  225. return -1;
  226. }
  227. int32_t BitfieldMan::getFirstMissingUnusedIndex() const {
  228. for(int32_t i = 0; i < bitfieldLength; ++i) {
  229. unsigned char bit = ~bitfield[i] & ~useBitfield[i];
  230. if(filterEnabled) {
  231. bit &= filterBitfield[i];
  232. }
  233. for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
  234. unsigned char mask = 1 << bs;
  235. if(bit & mask) {
  236. return i*8+7-bs;
  237. }
  238. }
  239. }
  240. return -1;
  241. }
  242. int32_t BitfieldMan::getMissingIndex() const {
  243. unsigned char* tempBitfield = new unsigned char[bitfieldLength];
  244. for(int32_t i = 0; i < bitfieldLength; ++i) {
  245. tempBitfield[i] = ~bitfield[i];
  246. if(filterEnabled) {
  247. tempBitfield[i] &= filterBitfield[i];
  248. }
  249. }
  250. int32_t index = getMissingIndexRandomly(tempBitfield, bitfieldLength);
  251. delete [] tempBitfield;
  252. return index;
  253. }
  254. int32_t BitfieldMan::getMissingUnusedIndex() const {
  255. unsigned char* tempBitfield = new unsigned char[bitfieldLength];
  256. memset(tempBitfield, 0xff, bitfieldLength);
  257. int32_t index = getMissingUnusedIndex(tempBitfield, bitfieldLength);
  258. delete [] tempBitfield;
  259. return index;
  260. }
  261. // [startIndex, endIndex)
  262. class Range {
  263. public:
  264. int32_t startIndex;
  265. int32_t endIndex;
  266. Range(int32_t startIndex = 0, int32_t endIndex = 0):startIndex(startIndex),
  267. endIndex(endIndex) {}
  268. int32_t getSize() const {
  269. return endIndex-startIndex;
  270. }
  271. int32_t getMidIndex() const {
  272. return (endIndex-startIndex)/2+startIndex;
  273. }
  274. bool operator<(const Range& range) const {
  275. return getSize() < range.getSize();
  276. }
  277. };
  278. int32_t BitfieldMan::getStartIndex(int32_t index) const {
  279. while(index < (int32_t)blocks &&
  280. (isUseBitSet(index) || isBitSet(index))) {
  281. index++;
  282. }
  283. if((int32_t)blocks <= index) {
  284. return -1;
  285. } else {
  286. return index;
  287. }
  288. }
  289. int32_t BitfieldMan::getEndIndex(int32_t index) const {
  290. while(index < (int32_t)blocks &&
  291. (!isUseBitSet(index) && !isBitSet(index))) {
  292. index++;
  293. }
  294. return index;
  295. }
  296. int32_t BitfieldMan::getSparseMissingUnusedIndex() const {
  297. Range maxRange;
  298. int32_t index = 0;
  299. int32_t blocks = countBlock();
  300. Range currentRange;
  301. while(index < (int32_t)blocks) {
  302. currentRange.startIndex = getStartIndex(index);
  303. if(currentRange.startIndex == -1) {
  304. break;
  305. }
  306. currentRange.endIndex = getEndIndex(currentRange.startIndex);
  307. if(maxRange < currentRange) {
  308. maxRange = currentRange;
  309. }
  310. index = currentRange.endIndex;
  311. }
  312. if(maxRange.getSize()) {
  313. if(maxRange.startIndex == 0) {
  314. return 0;
  315. } else {
  316. return maxRange.getMidIndex();
  317. }
  318. } else {
  319. return -1;
  320. }
  321. }
  322. BlockIndexes BitfieldMan::getAllMissingIndexes() const {
  323. BlockIndexes missingIndexes;
  324. for(int32_t i = 0; i < bitfieldLength; ++i) {
  325. unsigned char bit = ~bitfield[i];
  326. if(filterEnabled) {
  327. bit &= filterBitfield[i];
  328. }
  329. for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
  330. unsigned char mask = 1 << bs;
  331. if(bit & mask) {
  332. missingIndexes.push_back(i*8+7-bs);
  333. }
  334. }
  335. }
  336. return missingIndexes;
  337. }
  338. BlockIndexes BitfieldMan::getAllMissingIndexes(const unsigned char* peerBitfield, int32_t peerBitfieldLength) const {
  339. BlockIndexes missingIndexes;
  340. if(bitfieldLength != peerBitfieldLength) {
  341. return missingIndexes;
  342. }
  343. for(int32_t i = 0; i < bitfieldLength; ++i) {
  344. unsigned char bit = peerBitfield[i] & ~bitfield[i];
  345. if(filterEnabled) {
  346. bit &= filterBitfield[i];
  347. }
  348. for(int bs = 7; bs >= 0 && i*8+7-bs < blocks; bs--) {
  349. unsigned char mask = 1 << bs;
  350. if(bit & mask) {
  351. missingIndexes.push_back(i*8+7-bs);
  352. }
  353. }
  354. }
  355. return missingIndexes;
  356. }
  357. int32_t BitfieldMan::countMissingBlock() const {
  358. return cachedNumMissingBlock;
  359. }
  360. int32_t BitfieldMan::countMissingBlockNow() const {
  361. if(filterEnabled) {
  362. unsigned char* temp = new unsigned char[bitfieldLength];
  363. for(int32_t i = 0; i < bitfieldLength; ++i) {
  364. temp[i] = bitfield[i]&filterBitfield[i];
  365. }
  366. int32_t count = countSetBit(filterBitfield, bitfieldLength)-
  367. countSetBit(temp, bitfieldLength);
  368. delete [] temp;
  369. return count;
  370. } else {
  371. return blocks-countSetBit(bitfield, bitfieldLength);
  372. }
  373. }
  374. int32_t BitfieldMan::countBlock() const {
  375. if(filterEnabled) {
  376. return cachedNumFilteredBlock;
  377. } else {
  378. return blocks;
  379. }
  380. }
  381. int32_t BitfieldMan::countFilteredBlockNow() const {
  382. if(filterEnabled) {
  383. return countSetBit(filterBitfield, bitfieldLength);
  384. } else {
  385. return 0;
  386. }
  387. }
  388. bool BitfieldMan::setBitInternal(unsigned char* bitfield, int32_t index, bool on) {
  389. if((int32_t)blocks <= index) { return false; }
  390. unsigned char mask = 128 >> index%8;
  391. if(on) {
  392. bitfield[index/8] |= mask;
  393. } else {
  394. bitfield[index/8] &= ~mask;
  395. }
  396. return true;
  397. }
  398. bool BitfieldMan::setUseBit(int32_t index) {
  399. return setBitInternal(useBitfield, index, true);
  400. }
  401. bool BitfieldMan::unsetUseBit(int32_t index) {
  402. return setBitInternal(useBitfield, index, false);
  403. }
  404. bool BitfieldMan::setBit(int32_t index) {
  405. bool b = setBitInternal(bitfield, index, true);
  406. updateCache();
  407. return b;
  408. }
  409. bool BitfieldMan::unsetBit(int32_t index) {
  410. bool b = setBitInternal(bitfield, index, false);
  411. updateCache();
  412. return b;
  413. }
  414. bool BitfieldMan::isFilteredAllBitSet() const {
  415. if(filterEnabled) {
  416. for(int32_t i = 0; i < bitfieldLength; ++i) {
  417. if((bitfield[i]&filterBitfield[i]) != filterBitfield[i]) {
  418. return false;
  419. }
  420. }
  421. return true;
  422. } else {
  423. return isAllBitSet();
  424. }
  425. }
  426. bool BitfieldMan::isAllBitSet() const {
  427. for(int32_t i = 0; i < bitfieldLength-1; ++i) {
  428. if(bitfield[i] != 0xff) {
  429. return false;
  430. }
  431. }
  432. unsigned char b = ~((128 >> (blocks-1)%8)-1);
  433. if(bitfield[bitfieldLength-1] != b) {
  434. return false;
  435. }
  436. return true;
  437. }
  438. bool BitfieldMan::isBitSetInternal(const unsigned char* bitfield, int32_t index) const {
  439. if(index < 0 || (int32_t)blocks <= index) { return false; }
  440. unsigned char mask = 128 >> index%8;
  441. return (bitfield[index/8] & mask) != 0;
  442. }
  443. bool BitfieldMan::isBitSet(int32_t index) const {
  444. return isBitSetInternal(bitfield, index);
  445. }
  446. bool BitfieldMan::isUseBitSet(int32_t index) const {
  447. return isBitSetInternal(useBitfield, index);
  448. }
  449. void BitfieldMan::setBitfield(const unsigned char* bitfield, int32_t bitfieldLength) {
  450. if(this->bitfieldLength != bitfieldLength) {
  451. return;
  452. }
  453. memcpy(this->bitfield, bitfield, this->bitfieldLength);
  454. memset(this->useBitfield, 0, this->bitfieldLength);
  455. updateCache();
  456. }
  457. void BitfieldMan::clearAllBit() {
  458. memset(this->bitfield, 0, this->bitfieldLength);
  459. updateCache();
  460. }
  461. void BitfieldMan::setAllBit() {
  462. for(int32_t i = 0; i < blocks; ++i) {
  463. setBitInternal(bitfield, i, true);
  464. }
  465. updateCache();
  466. }
  467. void BitfieldMan::clearAllUseBit() {
  468. memset(this->useBitfield, 0, this->bitfieldLength);
  469. updateCache();
  470. }
  471. void BitfieldMan::setAllUseBit() {
  472. for(int32_t i = 0; i < blocks; ++i) {
  473. setBitInternal(useBitfield, i, true);
  474. }
  475. }
  476. bool BitfieldMan::setFilterBit(int32_t index) {
  477. return setBitInternal(filterBitfield, index, true);
  478. }
  479. void BitfieldMan::addFilter(int64_t offset, int64_t length) {
  480. if(!filterBitfield) {
  481. filterBitfield = new unsigned char[bitfieldLength];
  482. memset(filterBitfield, 0, bitfieldLength);
  483. }
  484. int32_t startBlock = offset/blockLength;
  485. int32_t endBlock = (offset+length-1)/blockLength;
  486. for(int i = startBlock; i <= endBlock && i < (int32_t)blocks; i++) {
  487. setFilterBit(i);
  488. }
  489. updateCache();
  490. }
  491. void BitfieldMan::enableFilter() {
  492. filterEnabled = true;
  493. updateCache();
  494. }
  495. void BitfieldMan::disableFilter() {
  496. filterEnabled = false;
  497. updateCache();
  498. }
  499. void BitfieldMan::clearFilter() {
  500. if(filterBitfield) {
  501. delete [] filterBitfield;
  502. filterBitfield = 0;
  503. }
  504. filterEnabled = false;
  505. updateCache();
  506. }
  507. bool BitfieldMan::isFilterEnabled() const {
  508. return filterEnabled;
  509. }
  510. int64_t BitfieldMan::getFilteredTotalLength() const {
  511. return cachedFilteredTotalLength;
  512. }
  513. int64_t BitfieldMan::getFilteredTotalLengthNow() const {
  514. if(!filterBitfield) {
  515. return 0;
  516. }
  517. int32_t filteredBlocks = countSetBit(filterBitfield, bitfieldLength);
  518. if(filteredBlocks == 0) {
  519. return 0;
  520. }
  521. if(isBitSetInternal(filterBitfield, blocks-1)) {
  522. return ((int64_t)filteredBlocks-1)*blockLength+getLastBlockLength();
  523. } else {
  524. return ((int64_t)filteredBlocks)*blockLength;
  525. }
  526. }
  527. int64_t BitfieldMan::getCompletedLength(bool useFilter) const {
  528. unsigned char* temp = new unsigned char[bitfieldLength];
  529. if(useFilter) {
  530. for(int32_t i = 0; i < bitfieldLength; ++i) {
  531. temp[i] = bitfield[i];
  532. if(filterEnabled) {
  533. temp[i] &= filterBitfield[i];
  534. }
  535. }
  536. } else {
  537. memcpy(temp, bitfield, bitfieldLength);
  538. }
  539. int32_t completedBlocks = countSetBit(temp, bitfieldLength);
  540. int64_t completedLength = 0;
  541. if(completedBlocks == 0) {
  542. completedLength = 0;
  543. } else {
  544. if(isBitSetInternal(temp, blocks-1)) {
  545. completedLength = ((int64_t)completedBlocks-1)*blockLength+getLastBlockLength();
  546. } else {
  547. completedLength = ((int64_t)completedBlocks)*blockLength;
  548. }
  549. }
  550. delete [] temp;
  551. return completedLength;
  552. }
  553. int64_t BitfieldMan::getCompletedLength() const {
  554. return cachedCompletedLength;
  555. }
  556. int64_t BitfieldMan::getCompletedLengthNow() const {
  557. return getCompletedLength(false);
  558. }
  559. int64_t BitfieldMan::getFilteredCompletedLength() const {
  560. return cachedFilteredComletedLength;
  561. }
  562. int64_t BitfieldMan::getFilteredCompletedLengthNow() const {
  563. return getCompletedLength(true);
  564. }
  565. void BitfieldMan::updateCache()
  566. {
  567. cachedNumMissingBlock = countMissingBlockNow();
  568. cachedNumFilteredBlock = countFilteredBlockNow();
  569. cachedFilteredTotalLength = getFilteredTotalLengthNow();
  570. cachedCompletedLength = getCompletedLengthNow();
  571. cachedFilteredComletedLength = getFilteredCompletedLengthNow();
  572. }
  573. bool BitfieldMan::isBitRangeSet(int32_t startIndex, int32_t endIndex) const
  574. {
  575. for(int32_t i = startIndex; i <= endIndex; ++i) {
  576. if(!isBitSet(i)) {
  577. return false;
  578. }
  579. }
  580. return true;
  581. }
  582. void BitfieldMan::unsetBitRange(int32_t startIndex, int32_t endIndex)
  583. {
  584. for(int32_t i = startIndex; i <= endIndex; ++i) {
  585. unsetBit(i);
  586. }
  587. updateCache();
  588. }
  589. bool BitfieldMan::isBitSetOffsetRange(int64_t offset, int64_t length) const
  590. {
  591. if(length <= 0) {
  592. return false;
  593. }
  594. if(totalLength <= offset) {
  595. return false;
  596. }
  597. if(totalLength < offset+length) {
  598. length = totalLength-offset;
  599. }
  600. int32_t startBlock = offset/blockLength;
  601. int32_t endBlock = (offset+length-1)/blockLength;
  602. for(int32_t i = startBlock; i <= endBlock; i++) {
  603. if(!isBitSet(i)) {
  604. return false;
  605. }
  606. }
  607. return true;
  608. }