diff --git a/fastlib/col/arraylist.h b/fastlib/col/arraylist.h index 97c4984707..ecbbdadda4 100644 --- a/fastlib/col/arraylist.h +++ b/fastlib/col/arraylist.h @@ -16,10 +16,10 @@ /** * Fast expandable array with debug-mode bounds checking. * - * This has roughly similar features to std::vector. However, instead of - * assuming the data type has a copy constructor, we assume it can be - * "relocated" to another memory address using realloc. - * The primary case where this assumption would be false is if objects have + * This has roughly similar features to std::vector. However, an ArrayList + * assumes that all objects can be relocated by just doing a shallow move + * with realloc, without performing a deep copy on every element. + * This means you cannot use an ArrayList if objects have * pointers to fields within themselves -- this isn't a very common * programming practice. Like std::vector, it is unwise to have * external pointers to objects inside this array, if you expect that the @@ -41,7 +41,7 @@ * ArrayList list; * list.Init(); * while (some_condition) { - * list.AddBack()->Init(arguments, for, MyType); + * list.AddBack()->Init(x, y, z); * } * @endcode * @@ -51,14 +51,21 @@ * ArrayList list; * list.Init(55); * for (int i = 0; i < 55; i++) { - * list[i].Init(arguments, for, MyType); + * list[i].Init(x, y, z); * } * @endcode * + * In addition, ArrayList has all the definitions necessary for the object + * traversal system, so it is suitable for use with THOR's automatic + * serialization and deserialization. + * */ template class ArrayList { public: + /** + * The element type. + */ typedef TElement Element; private: @@ -208,6 +215,9 @@ class ArrayList { /** * Steals the contents of another ArrayList, initializing this ArrayList and * destructing the other ArrayList. + * + * WARNING: If the other ArrayList falls out of scope without being + * reinitialized, the program will fail. */ void StealDestruct(ArrayList* other) { DEBUG_ASSERT_MSG(size_ == BIG_BAD_NUMBER, "reinitialization not allowed"); diff --git a/fastlib/thor/cachearray.h b/fastlib/thor/cachearray.h index 7b163b403c..cbe0f4246f 100644 --- a/fastlib/thor/cachearray.h +++ b/fastlib/thor/cachearray.h @@ -103,11 +103,9 @@ class CacheArray { * "locked" blocks! This maximum should be 32 for most use cases, with 64 * giving a nice balance between efficiency and memory usage -- given the * worst-case of 32 used blocks, the mean search time for an empty FIFO - * entry is two, and only 64 blocks are forced into RAM. + * entry is about three, and only 48 blocks are forced into RAM. */ static const int FIFO_SIZE = 64; - /** Bitmask for doing modulo FIFO_SIZE. */ - static const int FIFO_MASK = (FIFO_SIZE-1); protected: /** The metadata array, but adjusted (see how it is used in code). */ diff --git a/fastlib/thor/cachearray_impl.h b/fastlib/thor/cachearray_impl.h index 9817a147c9..a8085a8419 100644 --- a/fastlib/thor/cachearray_impl.h +++ b/fastlib/thor/cachearray_impl.h @@ -258,22 +258,33 @@ typename CacheArray::Element* CacheArray::HandleCacheMiss_( // unlocked item -- the most likely case is that the first item in the // fifo is non-negative (i.e. it exists) and it's most likely not locked for (;;) { - fifo_index_ = (fifo_index_+1) & FIFO_MASK; + if (unlikely(fifo_index_ == 0)) { + fifo_index_ = FIFO_SIZE; + } + + fifo_index_--; victim = fifo_[fifo_index_]; + if (unlikely(victim < 0)) { break; } + victim_metadata = adjusted_metadatas_ + victim; + if (unlikely(victim_metadata->lock_count != 0)) { + // the block was locked continue; } + DEBUG_ASSERT(victim_metadata->data != NULL); if (BlockDevice::can_write(mode_)) { cache_->StopWrite(victim); } else { cache_->StopRead(victim); } + victim_metadata->data = NULL; + break; } diff --git a/fastlib/thor/gnp.h b/fastlib/thor/gnp.h index 2059a5c780..317fd9433c 100644 --- a/fastlib/thor/gnp.h +++ b/fastlib/thor/gnp.h @@ -63,10 +63,11 @@ class ThorVectorPoint { * with Init. * * @param param ignored + * @param index the index of the point, ignored * @param data the vector data read from file */ template - void Set(const Param& param, const Vector& data) { + void Set(const Param& param, index_t index, const Vector& data) { vec_.CopyValues(data); } }; @@ -77,8 +78,6 @@ struct BlankDelta { public: template void Init(const Param& param) {} - template - void ApplyDelta(const Param& param, const BlankDelta& other) {} }; struct BlankQPostponed { diff --git a/fastlib/thor/thor_utils_impl.h b/fastlib/thor/thor_utils_impl.h index 6068e5466a..48f438c7a9 100644 --- a/fastlib/thor/thor_utils_impl.h +++ b/fastlib/thor/thor_utils_impl.h @@ -104,9 +104,9 @@ index_t thor::ReadPointsMaster( } else if (is_done) { break; } else { - CacheWrite point(&points_array, - points_array.AllocD(rpc::rank(), 1)); - point->Set(param, vector); + index_t i = points_array.AllocD(rpc::rank(), 1); + CacheWrite point(&points_array, i); + point->Set(param, i, vector); n_points++; } } diff --git a/fastlib/u/garryb/nbr/affinity.cc b/fastlib/u/garryb/nbr/affinity.cc index a26c35c9f9..ab4f7ff7c5 100644 --- a/fastlib/u/garryb/nbr/affinity.cc +++ b/fastlib/u/garryb/nbr/affinity.cc @@ -207,7 +207,7 @@ struct AffinityCommon { info_.rho = param.pref; } - void Set(const Param& param, const Vector& data) { + void Set(const Param& param, index_t index, const Vector& data) { vec_.CopyValues(data); // Randomly prime points to be exemplars. if (math::Random(0.0, 1.0) < param.prime) {