00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef OR_TOOLS_BASE_SPARSETABLE_H_
00015 #define OR_TOOLS_BASE_SPARSETABLE_H_
00016
00017 #include <vector>
00018 #include "base/logging.h"
00019
00020 namespace operations_research {
00021
00022 template <class T> class sparsetable {
00023 public:
00024 sparsetable() : size_(0) {}
00025
00026 void resize(int new_size) {
00027 CHECK_GE(new_size, 0);
00028 size_ = new_size;
00029 const int reduced_size = (size_ + kBlockSize - 1) / kBlockSize;
00030 if (reduced_size != elements_.size()) {
00031 elements_.resize(reduced_size);
00032 masks_.resize(reduced_size, 0U);
00033 }
00034 }
00035
00036 const T& get(int index) const {
00037 DCHECK_GE(index, 0);
00038 DCHECK_LT(index, size_);
00039 DCHECK(test(index));
00040 return elements_[index / kBlockSize][index % kBlockSize];
00041 }
00042
00043 void set(int index, const T& elem) {
00044 const int offset = index / kBlockSize;
00045 const int pos = index % kBlockSize;
00046 if (elements_[offset].size() == 0) {
00047 elements_[offset].resize(kBlockSize);
00048 }
00049 elements_[offset][index % kBlockSize] = elem;
00050 masks_[offset] |= (1U << pos);
00051 }
00052
00053 bool test(int index) const {
00054 const int offset = index / kBlockSize;
00055 const int pos = index % kBlockSize;
00056 return ((masks_[offset] & (1U << pos)) != 0);
00057 }
00058
00059 int size() const { return size_; }
00060 private:
00061 static const int kBlockSize = 32;
00062
00063 int size_;
00064 std::vector<std::vector<T> > elements_;
00065 std::vector<uint32> masks_;
00066 };
00067 }
00068
00069 #endif // OR_TOOLS_BASE_SPARSETABLE_H_