// Dataset.cxx #include "dataset_base/Dataset.h" #include #include #include #include "dataset_id/SimpleUniqueIdGenerator.h" #include "dataset_id/DatasetId.h" #include "dataset_base/Location.h" using std::string; using std::ostream; using std::cerr; using std::ostringstream; using std::setw; using dset::Content; using dset::Location; using dset::Dataset; using dset::DatasetList; typedef Dataset::Time Time; typedef std::set DatasetSet; //********************************************************************** // Local definitions. //********************************************************************** namespace { // ID generator. UniqueIdGenerator*& pgen() { static UniqueIdGenerator* val = 0; return val; } // Allocated datsets. DatasetSet alldsts; unsigned long ctor_count = 0; unsigned long dtor_count = 0; unsigned long error_count = 0; } // end unnamed namespace //********************************************************************** // Static members. //********************************************************************** // Return the dataset ID generator. UniqueIdGenerator& Dataset::id_generator() { if ( pgen() == 0 ) { pgen() = UniqueIdGenerator::find_generator("Dataset"); if ( pgen() == 0 ) { pgen() = new SimpleUniqueIdGenerator; } } return *pgen(); } //********************************************************************** // Reset the dataset ID generator. void Dataset::reset_id_generator() { delete pgen(); pgen() = 0; } //********************************************************************** // Make the ID generator local. void Dataset::set_local_id_generator() { if ( pgen() != 0 ) { if ( pgen()->is_valid() && ! pgen()->is_global() ) return; delete pgen(); } pgen() = new SimpleUniqueIdGenerator; } //********************************************************************** // Report on dataset memory usage. string Dataset::memory_report() { ostringstream ssout; ssout << "Dataset memory report"; if ( ctor_count == 0 ) { ssout << "\n No datasets created"; return ssout.str(); } int width = int(log10(double(ctor_count))) + 1; DatasetSet::size_type nrem = ctor_count - dtor_count; ssout << "\n # created: " << setw(width) << ctor_count; ssout << "\n # deleted: " << setw(width) << dtor_count; ssout << "\n # remaining: " << setw(width) << nrem; if ( alldsts.size() != nrem ) { ssout << "\n # recorded: " << setw(width) << alldsts.size(); } if ( error_count != 0 ) { ssout << "\n error count: " << error_count; } size_t mem = 0; for ( DatasetSet::const_iterator idst=alldsts.begin(); idst!=alldsts.end(); ++idst ) { mem += (**idst).memsize(); } string unit = "bytes"; if ( mem > 100000000 ) { mem /= 1000000; unit = "MB"; } else if ( mem > 100000 ) { mem /= 1000; unit = "KB"; } ssout << "\n memory usage: " << mem << " " << unit; return ssout.str(); } //********************************************************************** // Member functions. //********************************************************************** // Constructor. Dataset::Dataset() { ++ctor_count; if ( alldsts.find(this) == alldsts.end() ) { alldsts.insert(this); } else { cerr << "Dataset::ctor: Dataset already exists" << std::endl; ++error_count; } } //********************************************************************** // Destructor. Dataset::~Dataset() { ++dtor_count; DatasetSet::iterator idst = alldsts.find(this); if ( alldsts.find(this) == alldsts.end() ) { cerr << "Dataset::ctor: Dataset already deleted" << std::endl; ++error_count; } else { alldsts.erase(idst); } } //********************************************************************** // Type. string Dataset::fulltype() const { return "Dataset"; } //********************************************************************** // Validity. bool Dataset::is_valid() const { return id().is_valid(); } //********************************************************************** // Error. int Dataset::error() const { if ( is_valid() ) return 0; return 9999; } //********************************************************************** // Emptiness. bool Dataset::is_empty() const { return true; } //********************************************************************** // Content. const Content& Dataset::content() const { static const Content empty_content; return empty_content; } //********************************************************************** // Virtualness. bool Dataset::is_virtual() const { return location().is_empty(); } //********************************************************************** // Location. const Location& Dataset::location() const { static const Location empty_location; return empty_location; } //********************************************************************** // Interface location. const Location& Dataset::interface_location() const { return location(); } //********************************************************************** // Constituents ID's. const DatasetIdList& Dataset::constituent_ids() const { static const DatasetIdList empty_dids; return empty_dids; } //********************************************************************** // Constituents. const DatasetList& Dataset::constituents() const { static const DatasetList empty_dsts; return empty_dsts; } //********************************************************************** // Release. int Dataset::release() const { return 0; } //********************************************************************** // Output stream. ostream& Dataset::ostr(ostream& str, string indent, string repurl) const { return base_ostr(str, indent, repurl); } //********************************************************************** // Print. void Dataset::display() const { ostr(std::cout, ""); std::cout << std::endl; } //********************************************************************** // Base output stream. ostream& Dataset:: base_ostr(ostream& str, string indent, string repurl) const { if ( ! is_valid() ) { str << indent << "Invalid dataset"; return str; } str << indent << fulltype() << " " << id().to_string() << " with"; if ( parent() == 0 ) { str << " no parent"; } else { str << " parent " << parent()->id().to_string(); } str << " is "; if ( ! is_locked() ) str << "un"; str << "locked and "; if ( ! is_empty() ) str << "not "; str << "empty"; if ( owner().size() ) { str << "\n Owner: " << owner(); } if ( create_time() > 0 ) { char ctim[256]; const char* fmt = "%Y %B %d %X"; Time tim = create_time(); strftime(ctim, 256, fmt, localtime(&tim)); str << "\n Create time: " << ctim; } if ( ! content().is_empty() ) { str << '\n'; content().ostr(str, indent + " "); } if ( is_virtual() ) { str << "\n" << indent << " Dataset is virtual"; } if ( ! location().is_empty() ) { str << '\n'; location().ostr(str, indent + " "); } if ( interface_location() != location() ) { str << '\n'; interface_location().ostr(str, indent + " ", "Interface location"); } if ( constituent_ids().size() ) { str << "\n"; constituent_ids().ostr(str, indent + " ", repurl); } return str; } //********************************************************************** // Web page. Text Dataset:: web_page(string baseurl, string repurl, string entry) const { Text wp; wp.append(""); // Display dataset. if ( entry == "" ) { string header = "Dataset " + id().to_string(); wp.append("" + header + ""); //wp.append("

" + header + "

"); wp.append("
");
    ostringstream sout;
    ostr(sout, "", repurl);
    wp.append(sout.str());
    wp.append("
"); } else { wp.append("Dataset::web_page: Invalid entry " + entry); } wp.append(""); return wp; } //********************************************************************** // Free functions. //********************************************************************** // Ordering. bool dset::operator<(const Dataset& lhs, const Dataset& rhs) { return lhs.id() < rhs.id(); } //********************************************************************** // List validity. bool dset::is_valid(const dset::DatasetList& rhs) { for ( DatasetList::const_iterator ipds=rhs.begin(); ipds!=rhs.end(); ++ipds ) { const Dataset* pdst = *ipds; if ( pdst == 0 || ! pdst->is_valid() ) { return false; } } return true; } //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const Dataset& rhs) { return rhs.ostr(lhs, ""); } //********************************************************************** // List output stream. ostream& operator<<(ostream& lhs, const DatasetList& rhs) { DatasetList::size_type count = rhs.size(); lhs << "Dataset list has " << count << " entr"; if ( count == 1 ) { lhs << "y"; } else { lhs << "ies"; } if ( count > 0 ) { lhs << ":"; } for ( DatasetList::const_iterator idst=rhs.begin(); idst!=rhs.end(); ++idst ) { const Dataset* pdst = *idst; lhs << "\n"; if ( pdst == 0 ) { lhs << " Null dataset"; } else { pdst->base_ostr(lhs, " "); } } return lhs; } //**********************************************************************