// SimpleUniqueIdGenerator.h #ifndef SimpleUniqueIdGenerator_H #define SimpleUniqueIdGenerator_H // Class to generate unique ID's (class UniqueId). // // This generator has a fixed collection index and holds its state in // a file. The entry index is incremented each time an ID is // generated. // // The generated ID's will be unique as long as any collections // index is only used once and the corresponding collection // state file is not replicated. // // State files for collection indices in the range 1-999 can be // created with method create_collection. These are intended for use in // testing and should not be used for production. // // State files for production must be created externally. Typically // this would be a central server for each context that guarantees // that each value of the collection index is only assigned once. // // The collection state file has the name // // UGDIR/CONTEXT/cccccccccc // UGDIR = base directory // CONTEXT = name of the unique index context // ID's are only unique within this context // ccccccccc = zero-padded collection index // // The file has the following format: // // CONTEXT // cccccccccc // eeeeeeeeee // // ccc = context index // eee = last assigned entry index // // UGDIR is defaults ./UniqueId but may be set using the static method // base_directory(...). // // Any remaining SimpleUniqueIdGenerators are automatically deleted // during C++ termination so that their associated state files are // properly updated. If the program does not terminate normally, then // its state file fname will be absent and a copy of the orignal version // of this file will be stored in fname... // // Make this the classs the default generator with: // UniqueIdGenerator::set_generator( // "SimpleUniqueIdGenerator:/home/myids:5:true" // ); // This example sets the base directory to /home/myids, the maximimum // number of retries to 5, and verbose to true. #include #include "dataset_util/PThreadMutex.h" #include "dataset_id/UniqueId.h" #include "dataset_id/UniqueIdGenerator.h" class SimpleUniqueIdGenerator : public UniqueIdGenerator { public: // typdefs typedef UniqueId::Index Index; private: // data // Context. std::string _context; // Collection index. Index _col; // Last entry index. Index _ent; // Collection state file name. std::string _fname; // Name for file when being accessed. std::string m_savename; // Valid. bool _valid; // Is the collection (and its file) open? bool _open; // Process managing this collection. // Used to prevent child processes from closing. int m_pid; public: // Static functions. // Find and opens an available collection. // If a directory is found, then maxtry attempts are made to find // an available collection in that directory. // There is a random delay of 1-5 seconds between attempts. // If maxtry is set to zero, a default value (presently 10) is used. // If verbose is set, a message is written to cerr for each failure. // Returns zero if one cannot be found. static SimpleUniqueIdGenerator* find_generator(std::string context, unsigned int maxtry =0, bool verbose =true); // Create a collection for a test generator. // Allowed collection indices are 1-999. // The collection must not yet exist. // Returns 0 for success. static int create_collection(std::string context, Index col, Index ent); // Define the base directory. // This directory should exist and contain the relevant collection // subdirectories. // No change if the argument is blank. // Returns the base directory. static std::string base_directory(std::string dir =""); // Set this class as the default generator. // I.e. UniqueIdGenerator::find_generator(...) will use this class. // Returns 0 for success. static int set_as_default(std::string basedir ="", unsigned int maxtry =0, bool verbose =true); private: // functions // Constructor from a file. // Object is left in an invalid state if the file cannot be opened, // cannot be read or if it has the wrong collection ID. SimpleUniqueIdGenerator(std::string filename); // Hide the copy constructor. SimpleUniqueIdGenerator(const SimpleUniqueIdGenerator& rhs); // Hide assignment. SimpleUniqueIdGenerator& operator=(const SimpleUniqueIdGenerator& rhs); public: // functions // Constructor for a local generator (collection ID 0). // ID's are only unique within the context of this instance. SimpleUniqueIdGenerator(); // Destructor. // Closes the collection if it is open. ~SimpleUniqueIdGenerator(); // Return the next ID. // Closes the generator after the last ID is assigned. UniqueId next(); // Record the current state in the save file. // This is called by next. int save(); // Close the collection. // Returns zero for success. // Typical failure is insufficint space or quota. int close(); // Return the mutex. PThreadMutex& mutex() const { return m_mtx; } public: // const functions // Is this a valid generator? bool is_valid() const { return _valid; } // Is this a global generator, i.e. one for which ID's can be expected // to be unique even if they are generated in different processes. bool is_global() const { return is_valid() && _col!=0; } // Return the context. std::string context() const { return _context; } // Return the collection index. Index collection() const { return _col; } // Return the number of ID's already assigned from this collection. Index size_assigned() const { return _ent; } // Return the number of ID's remaining in this collection. Index size_remaining() const; // Return the filename. std::string filename() const { return _fname; } // Is the generator open? bool is_open() const { return _valid && _open; } // Mutex. mutable PThreadMutex m_mtx; // Output stream. std::ostream& ostr(std::ostream& lhs) const; }; #endif