sparseArray.cxx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. // Filename: sparseArray.cxx
  2. // Created by: drose (14Feb07)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "sparseArray.h"
  15. #include "bitArray.h"
  16. TypeHandle SparseArray::_type_handle;
  17. ////////////////////////////////////////////////////////////////////
  18. // Function: SparseArray::Constructor (from BitArray)
  19. // Access: Published
  20. // Description:
  21. ////////////////////////////////////////////////////////////////////
  22. SparseArray::
  23. SparseArray(const BitArray &from) {
  24. bool empty_bit = from.get_highest_bits();
  25. _inverse = empty_bit;
  26. int begin = 0;
  27. bool current_state = from.get_bit(0);
  28. int i = 0;
  29. // By including get_num_bits()--one more than the last bit--in this
  30. // traversal, we guarantee that we will end on the empty_bit state
  31. // (because the last bit we visit will be one of the highest_bits).
  32. while (i <= from.get_num_bits()) {
  33. if (from.get_bit(i) != current_state) {
  34. // End of a run.
  35. if (current_state != empty_bit) {
  36. Subrange range(begin, i);
  37. _subranges.push_back(range);
  38. }
  39. begin = i;
  40. current_state = !current_state;
  41. }
  42. ++i;
  43. }
  44. nassertv(current_state == empty_bit);
  45. }
  46. ////////////////////////////////////////////////////////////////////
  47. // Function: SparseArray::get_num_on_bits
  48. // Access: Published
  49. // Description: Returns the number of bits that are set to 1 in the
  50. // array. Returns -1 if there are an infinite number of
  51. // 1 bits.
  52. ////////////////////////////////////////////////////////////////////
  53. int SparseArray::
  54. get_num_on_bits() const {
  55. if (_inverse) {
  56. return -1;
  57. }
  58. int result = 0;
  59. Subranges::const_iterator si;
  60. for (si = _subranges.begin(); si != _subranges.end(); ++si) {
  61. result += (*si)._end - (*si)._begin;
  62. }
  63. return result;
  64. }
  65. ////////////////////////////////////////////////////////////////////
  66. // Function: SparseArray::get_num_off_bits
  67. // Access: Published
  68. // Description: Returns the number of bits that are set to 0 in the
  69. // array. Returns -1 if there are an infinite number of
  70. // 0 bits.
  71. ////////////////////////////////////////////////////////////////////
  72. int SparseArray::
  73. get_num_off_bits() const {
  74. if (!_inverse) {
  75. return -1;
  76. }
  77. int result = 0;
  78. Subranges::const_iterator si;
  79. for (si = _subranges.begin(); si != _subranges.end(); ++si) {
  80. result += (*si)._end - (*si)._begin;
  81. }
  82. return result;
  83. }
  84. ////////////////////////////////////////////////////////////////////
  85. // Function: SparseArray::get_lowest_on_bit
  86. // Access: Published
  87. // Description: Returns the index of the lowest 1 bit in the array.
  88. // Returns -1 if there are no 1 bits or if there are an
  89. // infinite number of 1 bits.
  90. ////////////////////////////////////////////////////////////////////
  91. int SparseArray::
  92. get_lowest_on_bit() const {
  93. if (_inverse) {
  94. return -1;
  95. }
  96. if (_subranges.empty()) {
  97. return -1;
  98. }
  99. return _subranges[0]._begin;
  100. }
  101. ////////////////////////////////////////////////////////////////////
  102. // Function: SparseArray::get_lowest_off_bit
  103. // Access: Published
  104. // Description: Returns the index of the lowest 0 bit in the array.
  105. // Returns -1 if there are no 0 bits or if there are an
  106. // infinite number of 1 bits.
  107. ////////////////////////////////////////////////////////////////////
  108. int SparseArray::
  109. get_lowest_off_bit() const {
  110. if (!_inverse) {
  111. return -1;
  112. }
  113. if (_subranges.empty()) {
  114. return -1;
  115. }
  116. return _subranges[0]._begin;
  117. }
  118. ////////////////////////////////////////////////////////////////////
  119. // Function: SparseArray::get_highest_on_bit
  120. // Access: Published
  121. // Description: Returns the index of the highest 1 bit in the array.
  122. // Returns -1 if there are no 1 bits or if there an
  123. // infinite number of 1 bits.
  124. ////////////////////////////////////////////////////////////////////
  125. int SparseArray::
  126. get_highest_on_bit() const {
  127. if (_inverse) {
  128. return -1;
  129. }
  130. if (_subranges.empty()) {
  131. return -1;
  132. }
  133. return _subranges[_subranges.size() - 1]._end - 1;
  134. }
  135. ////////////////////////////////////////////////////////////////////
  136. // Function: SparseArray::get_highest_off_bit
  137. // Access: Published
  138. // Description: Returns the index of the highest 0 bit in the array.
  139. // Returns -1 if there are no 0 bits or if there an
  140. // infinite number of 1 bits.
  141. ////////////////////////////////////////////////////////////////////
  142. int SparseArray::
  143. get_highest_off_bit() const {
  144. if (!_inverse) {
  145. return -1;
  146. }
  147. if (_subranges.empty()) {
  148. return -1;
  149. }
  150. return _subranges[_subranges.size() - 1]._end - 1;
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: SparseArray::get_next_higher_different_bit
  154. // Access: Published
  155. // Description: Returns the index of the next bit in the array, above
  156. // low_bit, whose value is different that the value of
  157. // low_bit. Returns low_bit again if all bits higher
  158. // than low_bit have the same value.
  159. //
  160. // This can be used to quickly iterate through all of
  161. // the bits in the array.
  162. ////////////////////////////////////////////////////////////////////
  163. int SparseArray::
  164. get_next_higher_different_bit(int low_bit) const {
  165. Subrange range(low_bit, low_bit + 1);
  166. Subranges::const_iterator si = _subranges.lower_bound(range);
  167. if (si == _subranges.end()) {
  168. // That was the end of the array.
  169. return low_bit;
  170. }
  171. if (low_bit >= (*si)._begin) {
  172. return (*si)._end;
  173. }
  174. int next = (*si)._begin;
  175. if (si != _subranges.begin()) {
  176. --si;
  177. if (low_bit < (*si)._end) {
  178. return (*si)._end;
  179. }
  180. }
  181. return next;
  182. }
  183. ////////////////////////////////////////////////////////////////////
  184. // Function: SparseArray::has_bits_in_common
  185. // Access: Published
  186. // Description: Returns true if this SparseArray has any "one" bits in
  187. // common with the other one, false otherwise.
  188. //
  189. // This is equivalent to (array & other) != 0, but may
  190. // be faster.
  191. ////////////////////////////////////////////////////////////////////
  192. bool SparseArray::
  193. has_bits_in_common(const SparseArray &other) const {
  194. if (_inverse && other._inverse) {
  195. // Yup, in fact we have an infinite number of bits in common.
  196. return true;
  197. }
  198. if (_inverse != other._inverse) {
  199. // We'll handle this tricky case the lazy way.
  200. return !(*this & other).is_zero();
  201. }
  202. // Actually, we'll handle this easy case the lazy way too. Maybe
  203. // later we'll do this smarter.
  204. return !(*this & other).is_zero();
  205. }
  206. ////////////////////////////////////////////////////////////////////
  207. // Function: SparseArray::output
  208. // Access: Published
  209. // Description:
  210. ////////////////////////////////////////////////////////////////////
  211. void SparseArray::
  212. output(ostream &out) const {
  213. out << "[ ";
  214. if (_inverse) {
  215. out << "all except: ";
  216. }
  217. Subranges::const_iterator si;
  218. for (si = _subranges.begin(); si != _subranges.end(); ++si) {
  219. if ((*si)._end == (*si)._begin + 1) {
  220. // A single element.
  221. out << (*si)._begin << ", ";
  222. } else {
  223. // A range of elements.
  224. out << (*si)._begin << "-" << ((*si)._end - 1) << ", ";
  225. }
  226. }
  227. out << "]";
  228. }
  229. ////////////////////////////////////////////////////////////////////
  230. // Function: SparseArray::compare_to
  231. // Access: Published
  232. // Description: Returns a number less than zero if this SparseArray
  233. // sorts before the indicated other SparseArray, greater
  234. // than zero if it sorts after, or 0 if they are
  235. // equivalent. This is based on the same ordering
  236. // defined by operator <.
  237. ////////////////////////////////////////////////////////////////////
  238. int SparseArray::
  239. compare_to(const SparseArray &other) const {
  240. if (_inverse != other._inverse) {
  241. return _inverse ? 1 : -1;
  242. }
  243. Subranges::const_reverse_iterator ai = _subranges.rbegin();
  244. Subranges::const_reverse_iterator bi = other._subranges.rbegin();
  245. while (ai != _subranges.rend() && bi != other._subranges.rend()) {
  246. if ((*ai)._end < (*bi)._end) {
  247. // B is higher.
  248. return -1;
  249. } else if ((*bi)._end < (*ai)._end) {
  250. // A is higher.
  251. return 1;
  252. } else if ((*ai)._begin < (*bi)._begin) {
  253. // A is higher.
  254. return 1;
  255. } else if ((*bi)._begin < (*ai)._begin) {
  256. // B is higher.
  257. return -1;
  258. }
  259. --ai;
  260. --bi;
  261. }
  262. if (ai != _subranges.rend()) {
  263. // A is higher.
  264. return 1;
  265. }
  266. if (bi != other._subranges.rend()) {
  267. // B is higher.
  268. return -1;
  269. }
  270. return 0;
  271. }
  272. ////////////////////////////////////////////////////////////////////
  273. // Function: SparseArray::operator &=
  274. // Access: Published
  275. // Description:
  276. ////////////////////////////////////////////////////////////////////
  277. void SparseArray::
  278. operator &= (const SparseArray &other) {
  279. // We do this the slow and stupid way. This could be done much
  280. // better with a little effort, but I'm not at all sure it's worth
  281. // the effort. If you need fast boolean operations, you should
  282. // probably be using a BitArray.
  283. if (_inverse && other._inverse) {
  284. do_union(other);
  285. } else if (!_inverse && !other._inverse) {
  286. do_intersection(other);
  287. } else if (_inverse && !other._inverse) {
  288. // a & b == b & a
  289. (*this) = other & (*this);
  290. } else if (!_inverse && other._inverse) {
  291. do_intersection_neg(other);
  292. } else {
  293. // TODO.
  294. nassertv(false);
  295. }
  296. }
  297. ////////////////////////////////////////////////////////////////////
  298. // Function: SparseArray::operator |=
  299. // Access: Published
  300. // Description:
  301. ////////////////////////////////////////////////////////////////////
  302. void SparseArray::
  303. operator |= (const SparseArray &other) {
  304. // We do this the slow and stupid way. This could be done much
  305. // better with a little effort, but I'm not at all sure it's worth
  306. // the effort. If you need fast boolean operations, you should
  307. // probably be using a BitArray.
  308. if (_inverse && other._inverse) {
  309. do_intersection(other);
  310. } else if (!_inverse && !other._inverse) {
  311. do_union(other);
  312. } else if (_inverse && !other._inverse) {
  313. do_intersection_neg(other);
  314. } else if (!_inverse && other._inverse) {
  315. // a | b == b | a
  316. (*this) = other | (*this);
  317. } else {
  318. nassertv(false);
  319. }
  320. }
  321. ////////////////////////////////////////////////////////////////////
  322. // Function: SparseArray::operator ^=
  323. // Access: Published
  324. // Description:
  325. ////////////////////////////////////////////////////////////////////
  326. void SparseArray::
  327. operator ^= (const SparseArray &other) {
  328. // We do this the slow and stupid way. This could be done much
  329. // better with a little effort, but I'm not at all sure it's worth
  330. // the effort. If you need fast boolean operations, you should
  331. // probably be using a BitArray.
  332. (*this) = ((*this) | other) & ~((*this) & other);
  333. }
  334. ////////////////////////////////////////////////////////////////////
  335. // Function: SparseArray::do_add_range
  336. // Access: Private
  337. // Description: Adds the consecutive range of integers beginning at
  338. // begin, but not including end, to the array. If this
  339. // range overlaps with another range already in the
  340. // array, the result is the union.
  341. ////////////////////////////////////////////////////////////////////
  342. void SparseArray::
  343. do_add_range(int begin, int end) {
  344. if (begin >= end) {
  345. // Empty range.
  346. return;
  347. }
  348. Subrange range(begin, end);
  349. Subranges::iterator si = _subranges.lower_bound(range);
  350. if (si == _subranges.end()) {
  351. if (!_subranges.empty()) {
  352. si = _subranges.begin() + _subranges.size() - 1;
  353. if ((*si)._end >= begin) {
  354. // The new range expands the last element of the array to the right.
  355. (*si)._end = end;
  356. // It might also expand it to the left; fall through.
  357. } else {
  358. // The new range is completely after the last element of the array.
  359. _subranges.push_back(range);
  360. return;
  361. }
  362. } else {
  363. // The new range is completely after the last element of the array.
  364. _subranges.push_back(range);
  365. return;
  366. }
  367. }
  368. nassertv((*si)._end >= end);
  369. if ((*si)._begin > end) {
  370. if (si != _subranges.begin()) {
  371. Subranges::iterator si2 = si;
  372. --si2;
  373. if ((*si2)._end >= begin) {
  374. // The new range expands an element within the array to the
  375. // right (but does not intersect the next element).
  376. (*si2)._end = end;
  377. // It might also expand it to the left; fall through.
  378. si = si2;
  379. } else {
  380. // The new range does not intersect any elements in the array.
  381. _subranges.insert_unverified(si, range);
  382. return;
  383. }
  384. } else {
  385. // The new range does not intersect any elements in the array.
  386. _subranges.insert_unverified(si, range);
  387. return;
  388. }
  389. }
  390. // Check if the new range overlaps with any elements to the left.
  391. while (si != _subranges.begin()) {
  392. Subranges::iterator si2 = si;
  393. --si2;
  394. if ((*si2)._end >= begin) {
  395. // The new range straddles two elements, so they get combined.
  396. (*si2)._end = (*si)._end;
  397. _subranges.erase(si);
  398. } else {
  399. // Stop here.
  400. break;
  401. }
  402. si = si2;
  403. }
  404. if ((*si)._begin > begin) {
  405. // The new range expands an element to the left.
  406. (*si)._begin = begin;
  407. }
  408. }
  409. ////////////////////////////////////////////////////////////////////
  410. // Function: SparseArray::do_remove_range
  411. // Access: Private
  412. // Description: Removes the consecutive range of integers beginning
  413. // at begin, but not including end, from the array.
  414. ////////////////////////////////////////////////////////////////////
  415. void SparseArray::
  416. do_remove_range(int begin, int end) {
  417. if (begin >= end) {
  418. // Empty range.
  419. return;
  420. }
  421. Subrange range(begin, end);
  422. Subranges::iterator si = _subranges.lower_bound(range);
  423. if (si == _subranges.end()) {
  424. if (!_subranges.empty()) {
  425. si = _subranges.begin() + _subranges.size() - 1;
  426. if ((*si)._end >= begin) {
  427. // The new range shortens the last element of the array on the right.
  428. end = min(end, (*si)._begin);
  429. (*si)._end = end;
  430. // It might also shorten it on the left; fall through.
  431. } else {
  432. // The new range is completely after the last element of the array.
  433. return;
  434. }
  435. } else {
  436. // The new range is completely after the last element of the array.
  437. return;
  438. }
  439. }
  440. nassertv((*si)._end >= end);
  441. if ((*si)._begin > end) {
  442. if (si != _subranges.begin()) {
  443. Subranges::iterator si2 = si;
  444. --si2;
  445. if ((*si2)._end >= begin) {
  446. // The new range shortens an element within the array on the
  447. // right (but does not intersect the next element).
  448. end = min(end, (*si2)._begin);
  449. (*si2)._end = end;
  450. // It might also shorten it on the left; fall through.
  451. si = si2;
  452. } else {
  453. // The new range does not intersect any elements in the array.
  454. return;
  455. }
  456. } else {
  457. // The new range does not intersect any elements in the array.
  458. return;
  459. }
  460. }
  461. if (end < (*si)._end) {
  462. // We must split an element into two.
  463. Subrange left_range((*si)._begin, begin);
  464. (*si)._begin = end;
  465. si = _subranges.insert_unverified(si, left_range);
  466. }
  467. // Check if the new range removes any elements to the left.
  468. while (begin <= (*si)._begin) {
  469. if (si == _subranges.begin()) {
  470. _subranges.erase(si);
  471. return;
  472. }
  473. Subranges::iterator si2 = si;
  474. --si2;
  475. _subranges.erase(si);
  476. si = si2;
  477. }
  478. (*si)._end = min((*si)._end, begin);
  479. }
  480. ////////////////////////////////////////////////////////////////////
  481. // Function: SparseArray::do_has_any
  482. // Access: Private
  483. // Description: Returns true if any of the consecutive range of
  484. // integers beginning at begin, but not including end,
  485. // appear in the array. Note that this will return
  486. // false for an empty range.
  487. ////////////////////////////////////////////////////////////////////
  488. bool SparseArray::
  489. do_has_any(int begin, int end) const {
  490. if (begin >= end) {
  491. // Empty range.
  492. return false;
  493. }
  494. Subrange range(begin, end);
  495. Subranges::const_iterator si = _subranges.lower_bound(range);
  496. if (si != _subranges.end() && end > (*si)._begin) {
  497. return true;
  498. }
  499. if (si != _subranges.begin()) {
  500. --si;
  501. if (begin < (*si)._end) {
  502. return true;
  503. }
  504. }
  505. return false;
  506. }
  507. ////////////////////////////////////////////////////////////////////
  508. // Function: SparseArray::do_has_all
  509. // Access: Private
  510. // Description: Returns true if all of the consecutive range of
  511. // integers beginning at begin, but not including end,
  512. // appear in the array. Note that this will return
  513. // true for an empty range.
  514. ////////////////////////////////////////////////////////////////////
  515. bool SparseArray::
  516. do_has_all(int begin, int end) const {
  517. if (begin >= end) {
  518. // Empty range.
  519. return true;
  520. }
  521. Subrange range(begin, end);
  522. Subranges::const_iterator si = _subranges.lower_bound(range);
  523. if (si != _subranges.end() && begin >= (*si)._begin) {
  524. return true;
  525. }
  526. return false;
  527. }
  528. ////////////////////////////////////////////////////////////////////
  529. // Function: SparseArray::do_intersection
  530. // Access: Private
  531. // Description: Removes from this array all of the elements that do
  532. // not appear in the other one.
  533. ////////////////////////////////////////////////////////////////////
  534. void SparseArray::
  535. do_intersection(const SparseArray &other) {
  536. if (_subranges.empty()) {
  537. return;
  538. }
  539. if (other._subranges.empty()) {
  540. _subranges.clear();
  541. return;
  542. }
  543. int my_begin = (*_subranges.begin())._begin;
  544. int other_begin = (*other._subranges.begin())._begin;
  545. do_remove_range(my_begin, other_begin);
  546. for (size_t i = 0; i < other._subranges.size() - 1; ++i) {
  547. do_remove_range(other._subranges[i]._end, other._subranges[i + 1]._begin);
  548. }
  549. int my_end = (*(_subranges.begin() + _subranges.size() - 1))._end;
  550. int other_end = (*(other._subranges.begin() + other._subranges.size() - 1))._end;
  551. do_remove_range(other_end, my_end);
  552. }
  553. ////////////////////////////////////////////////////////////////////
  554. // Function: SparseArray::do_union
  555. // Access: Private
  556. // Description: Adds to this array all of the elements that also
  557. // appear in the other one.
  558. ////////////////////////////////////////////////////////////////////
  559. void SparseArray::
  560. do_union(const SparseArray &other) {
  561. Subranges::const_iterator si;
  562. for (si = other._subranges.begin(); si != other._subranges.end(); ++si) {
  563. do_add_range((*si)._begin, (*si)._end);
  564. }
  565. }
  566. ////////////////////////////////////////////////////////////////////
  567. // Function: SparseArray::do_intersection_neg
  568. // Access: Private
  569. // Description: Removes from this array all of the elements that also
  570. // appear in the other one.
  571. ////////////////////////////////////////////////////////////////////
  572. void SparseArray::
  573. do_intersection_neg(const SparseArray &other) {
  574. Subranges::const_iterator si;
  575. for (si = other._subranges.begin(); si != other._subranges.end(); ++si) {
  576. do_remove_range((*si)._begin, (*si)._end);
  577. }
  578. }
  579. ////////////////////////////////////////////////////////////////////
  580. // Function: SparseArray::do_shift
  581. // Access: Private
  582. // Description: Shifts all the elements in the array by the indicated
  583. // amount.
  584. ////////////////////////////////////////////////////////////////////
  585. void SparseArray::
  586. do_shift(int offset) {
  587. if (offset != 0) {
  588. Subranges::iterator si;
  589. for (si = _subranges.begin(); si != _subranges.end(); ++si) {
  590. (*si)._begin += offset;
  591. (*si)._end += offset;
  592. }
  593. }
  594. }
  595. ////////////////////////////////////////////////////////////////////
  596. // Function: SparseArray::write_datagram
  597. // Access: Public
  598. // Description: Writes the contents of this object to the datagram
  599. // for shipping out to a Bam file.
  600. ////////////////////////////////////////////////////////////////////
  601. void SparseArray::
  602. write_datagram(BamWriter *manager, Datagram &dg) const {
  603. dg.add_uint32(_subranges.size());
  604. Subranges::const_iterator si;
  605. for (si = _subranges.begin(); si != _subranges.end(); ++si) {
  606. dg.add_int32((*si)._begin);
  607. dg.add_int32((*si)._end);
  608. }
  609. dg.add_bool(_inverse);
  610. }
  611. ////////////////////////////////////////////////////////////////////
  612. // Function: SparseArray::read_datagram
  613. // Access: Public
  614. // Description: Reads the object that was previously written to a Bam
  615. // file.
  616. ////////////////////////////////////////////////////////////////////
  617. void SparseArray::
  618. read_datagram(DatagramIterator &scan, BamReader *manager) {
  619. size_t num_subranges = scan.get_uint32();
  620. _subranges.reserve(num_subranges);
  621. for (size_t i = 0; i < num_subranges; ++i) {
  622. int begin = scan.get_int32();
  623. int end = scan.get_int32();
  624. _subranges.push_back(Subrange(begin, end));
  625. }
  626. _inverse = scan.get_bool();
  627. }