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