Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef ctrlplane_db_table_walker_h 6 : #define ctrlplane_db_table_walker_h 7 : 8 : #include <mutex> 9 : 10 : #include <boost/function.hpp> 11 : #include <boost/dynamic_bitset.hpp> 12 : 13 : #include "base/logging.h" 14 : #include "db/db_table.h" 15 : #include "db/db_table_partition.h" 16 : 17 : // A DB contains a TableWalker that is able to iterate though all the 18 : // entries in a certain routing table. 19 : class DBTableWalker { 20 : public: 21 : 22 : // Walker function: 23 : // Called for each DBEntry under a task that corresponds to the 24 : // specific partition. 25 : // arguments: DBTable partition and DBEntry. 26 : // returns: true (continue); false (stop). 27 : typedef boost::function<bool(DBTablePartBase *, DBEntryBase *)> WalkFn; 28 : 29 : // Called when all partitions are done iterating. 30 : typedef boost::function<void(DBTableBase *)> WalkCompleteFn; 31 : 32 : typedef int WalkId; 33 : 34 : static const int kIterationToYield = 1024; 35 : static const WalkId kInvalidWalkerId = -1; 36 : 37 : DBTableWalker(int task_id = -1); 38 : 39 : // Start a walk request on the specified table. If non null, 'key_start' 40 : // specifies the starting point for the walk. The walk is performed in 41 : // all table shards in parallel. 42 : WalkId WalkTable(DBTable *table, const DBRequestKey *key_start, 43 : WalkFn walker, WalkCompleteFn walk_complete, 44 : bool postpone_walk = false); 45 : 46 : // cancel a walk that may be in progress. This cannot be called from 47 : // the walker function itself. 48 : void WalkCancel(WalkId id); 49 : void WalkResume(WalkId id); 50 : 51 1800 : int task_id() const { return task_id_; } 52 : 53 2 : static void SetIterationToYield(int count) { 54 2 : max_iteration_to_yield_ = count; 55 2 : } 56 : 57 : private: 58 : static int max_iteration_to_yield_; 59 : 60 207 : static int GetIterationToYield() { 61 : static bool init_ = false; 62 : 63 207 : if (!init_) { 64 : 65 : // XXX To be used for testing purposes only. 66 1 : char *count_str = getenv("DB_ITERATION_TO_YIELD"); 67 1 : if (count_str) { 68 1 : max_iteration_to_yield_ = (int) strtol(count_str, NULL, 0); 69 1 : if (max_iteration_to_yield_ <= 0) 70 0 : max_iteration_to_yield_ = kIterationToYield; 71 : } 72 1 : init_ = true; 73 : } 74 : 75 207 : return max_iteration_to_yield_; 76 : } 77 : 78 : // A Walker allocated to iterator through a DBTable 79 : class Walker; 80 : 81 : // A Job for walking through the DBTablePartition 82 : class Worker; 83 : 84 : typedef std::vector<Walker *> WalkerList; 85 : typedef boost::dynamic_bitset<> WalkerMap; 86 : 87 : // Purge the walker after the walk is completed/cancelled 88 : void PurgeWalker(WalkId id); 89 : 90 : // List of walkers allocated 91 : int task_id_; 92 : std::mutex walkers_mutex_; 93 : WalkerList walkers_; 94 : WalkerMap walker_map_; 95 : }; 96 : 97 : #endif