/usr/include/dbstl_container.h is in libdb5.3-stl-dev 5.3.28-9+deb8u1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | /*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
#ifndef _DB_STL_CONTAINER_H__
#define _DB_STL_CONTAINER_H__
#include "dbstl_common.h"
#include "dbstl_resource_manager.h"
#include <assert.h>
START_NS(dbstl)
class ResourceManager;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// db_container class definition
//
// This class's begin_txn, commit/abort_txn is used to wrap each DB related
// operation inside dbstl. When auto commit is enabled, each operation will
// be auto committed before returning, and aborted when an exception is thrown.
//
// It also contains members to hold all needed parameters and flags for
// transaction and cursor related calls.
//
// Container classes will inherit from this class. Each container will enclose
// every db related operation with db_container::begin_txn and
// db_container::commit_txn, and if exception is not caught, abort_txn()
// should be called.
/** \defgroup dbstl_containers dbstl container classes
A dbstl container is very much like a C++ STL container. It stores a
collection of data items, or key/data pairs.
Each container is backed by a Berkeley DB database created in an explicit
database environment or an internal private environment; And the database
itself can be created explicitly with all kinds of configurations, or
by dbstl internally. For each type of container, some specific type of
database and/or configurations must be used or specified to the database
and its environment. dbstl will check the database and environment conform
to the requirement. When users don't have a chance to specify a container's
backing database and environment, like in copy constructors, dbstl will
create proper databases and/or environment for it. There are two helper
functions to make it easier to create/open an environment or database, they
are dbstl::open_db() and dbstl::open_env();
\sa dbstl::open_db() dbstl::open_env() db_vector db_map db_multimap db_set
db_multiset
*/
/** \ingroup dbstl_containers
@{
This class is the base class for all db container classes, you don't directly
use this class, but all container classes inherit from this class, so you need
to know the methods that can be accessed via concrete container classes.
This class is also used to support auto commit transactions. Autocommit is
enabled when DB_AUTO_COMMIT is set to the database or database environment
handle and the environment is transactional.
Inside dbstl, there are transactions begun and committed/aborted if the backing
database and/or environment requires auto commit, and there are cursors
opened internally, and you can set the flags used by the transaction and cursor
functions via set functions of this class.
All dbstl containers are fully multi-threaded, you should not need any
synchronization to use them in the correct way, but this class is not thread
safe, access to its members are not proctected by any mutex because the data
members of this class are supposed to be set before they are used,
and remain read only afterwards. If this is not the case, you must synchronize
the access.
*/
class _exported db_container
{
private:
// By default these flags are 0, users should configure these values
// on container initialization.
//
u_int32_t txn_begin_flags_, commit_flags_;
mutable u_int32_t cursor_oflags_;
// Berkeley DB database handle for each container. Subclasses do not
// need to define it.
//
Db *pdb_;
// Berkeley DB environment handle in which the db handle is opened.
DbEnv *dbenv_;
// db_map_iterator<> needs to know whether the container is a
// db_(multi)set or not
//
bool is_set_;
// Determined automatically, by inspecting users the Berkeley DB
// database and environment configuration options.
//
bool auto_commit_;
// If exisiting random temporary database name generation mechanism is
// still causing name clashes, users can set this global suffix number
// which will be append to each temporary database file name and by
// default it is 0. there is a dbstl::set_global_dbfile_suffix_number
// to do so.
static u_int32_t g_db_file_suffix_;
friend void set_global_dbfile_suffix_number(u_int32_t);
protected:
// Does not clone or copy data from database parameter.
// Return the db file name back in the dbfname parameter.
// We construct a default database name the user can rename it using
// either DbEnv::dbrename or Db::rename.
//
Db* clone_db_config(Db *dbp, std::string &dbfname);
Db* clone_db_config(Db *dbp);
// Store the name into name parameter whose length is n. Return -1 if
// not enough space.
int construct_db_file_name(std::string &filename) const;
// Check that this container and cntnr are backed by different databases
// and if any one of them is using transactions, both should be in the
// same transactional environment.
// Called by all deriving classes' methods
// which have a container parameter.
void verify_db_handles(const db_container &cntnr) const;
void open_db_handles(Db *&pdb, DbEnv *&penv, DBTYPE dbtype,
u_int32_t oflags, u_int32_t sflags);
inline void set_is_set(bool b)
{
is_set_ = b;
}
inline bool is_set() const
{
return is_set_;
}
// Database and environment handles and autocommit and is_set_ are
// not assigned, because they are the nature of my own db, not
// that of dbctnr.
inline const db_container &operator=(const db_container & dbctnr)
{
ASSIGNMENT_PREDCOND(dbctnr)
txn_begin_flags_ = dbctnr.txn_begin_flags_;
commit_flags_ = dbctnr.commit_flags_;
cursor_oflags_ = dbctnr.cursor_oflags_;
return dbctnr;
}
public:
/// Default constructor.
db_container();
/// Copy constructor.
/// The new container will be backed by another database within the
/// same environment unless dbctnr's backing database is in its own
/// internal private environment. The name of the database is coined
/// based on current time and thread id and some random number. If
/// this is still causing naming clashes, you can set a suffix number
/// via "set_global_dbfile_suffix_number" function; And following db
/// file will suffix this number in the file name for additional
/// randomness. And the suffix will be incremented after each such use.
/// You can change the file name via DbEnv::rename.
/// If dbctnr is using an anonymous database, the newly constructed
/// container will also use an anonymous one.
/// \param dbctnr The container to initialize this container.
db_container(const db_container &dbctnr);
/**
This constructor is not directly called by the user, but invoked by
constructors of concrete container classes. The statement about the
parameters applies to constructors of all container classes.
\param dbp Database handle. dbp is supposed to be opened inside envp.
Each dbstl container is backed by a Berkeley DB database, so dbstl
will create an internal anonymous database if dbp is NULL.
\param envp Environment handle. And envp can also be NULL, meaning the
dbp handle may be created in its internal private environment.
*/
db_container(Db *dbp, DbEnv *envp);
/// The backing database is not closed in this function. It is closed
/// when current thread exits and the database is no longer referenced
/// by any other container instances in this process.
/// In order to make the reference counting work alright, you must call
/// register_db(Db*) and register_db_env(DbEnv*) correctly.
/// \sa register_db(Db*) register_db_env(DbEnv*)
virtual ~db_container(){}
/// \name Get and set functions for data members.
/// Note that these functions are not thread safe, because all data
/// members of db_container are supposed to be set on container
/// construction and initialization, and remain read only afterwards.
//@{
/// Get the backing database's open flags.
/// \return The backing database's open flags.
inline u_int32_t get_db_open_flags() const
{
u_int32_t oflags;
pdb_->get_open_flags(&oflags);
return oflags;
}
/// Get the backing database's flags that are set via Db::set_flags()
/// function.
/// \return Flags set to this container's database handle.
inline u_int32_t get_db_set_flags() const
{
u_int32_t oflags;
pdb_->get_flags(&oflags);
return oflags;
}
/// Get the backing database's handle.
/// \return The backing database handle of this container.
inline Db* get_db_handle() const
{
return pdb_;
}
/// Get the backing database environment's handle.
/// \return The backing database environment handle of this container.
inline DbEnv* get_db_env_handle() const
{
return dbenv_;
}
/**
Set the underlying database's handle, and optionally environment
handle if the environment has also changed. That is, users can change
the container object's underlying database while the object is alive.
dbstl will verify that the handles set conforms to the concrete
container's requirement to Berkeley DB database/environment handles.
\param dbp The database handle to set.
\param newenv The database environment handle to set.
*/
void set_db_handle(Db *dbp, DbEnv *newenv = NULL);
/** Set the flags required by the Berkeley DB functions
DbEnv::txn_begin(), DbTxn::commit() and DbEnv::cursor(). These flags
will be set to this container's auto commit member functions when
auto commit transaction is used, except that cursor_oflags is set to
the Dbc::cursor when creating an iterator for this container.
By default the three flags are all zero.
You can also set the values of the flags individually by using the
appropriate set functions in this class. The corresponding get
functions return the flags actually used.
\param txn_begin_flags Flags to be set to DbEnv::txn_begin().
\param commit_flags Flags to be set to DbTxn::commit().
\param cursor_open_flags Flags to be set to Db::cursor().
*/
inline void set_all_flags(u_int32_t txn_begin_flags,
u_int32_t commit_flags, u_int32_t cursor_open_flags)
{
this->txn_begin_flags_ = txn_begin_flags;
this->commit_flags_ = commit_flags;
this->cursor_oflags_ = cursor_open_flags;
}
/// Set flag of DbEnv::txn_begin() call.
/// \param flag Flags to be set to DbEnv::txn_begin().
inline void set_txn_begin_flags(u_int32_t flag )
{
txn_begin_flags_ = flag;
}
/// Get flag of DbEnv::txn_begin() call.
/// \return Flags to be set to DbEnv::txn_begin().
inline u_int32_t get_txn_begin_flags() const
{
return txn_begin_flags_;
}
/// Set flag of DbTxn::commit() call.
/// \param flag Flags to be set to DbTxn::commit().
inline void set_commit_flags(u_int32_t flag)
{
commit_flags_ = flag;
}
/// Get flag of DbTxn::commit() call.
/// \return Flags to be set to DbTxn::commit().
inline u_int32_t get_commit_flags() const
{
return commit_flags_;
}
/// Get flag of Db::cursor() call.
/// \return Flags to be set to Db::cursor().
inline u_int32_t get_cursor_open_flags() const
{
return cursor_oflags_;
}
/// Set flag of Db::cursor() call.
/// \param flag Flags to be set to Db::cursor().
inline void set_cursor_open_flags(u_int32_t flag)
{
cursor_oflags_ = flag;
}
//@} // getter_setters
protected:
void init_members();
void init_members(Db *pdb, DbEnv *env);
void init_members(const db_container&cnt);
// Called internally by concrete container constructors. Verification
// is done by the specialized constructors
void set_db_handle_int(Db *dbp, DbEnv *envp)
{
this->pdb_ = dbp;
this->dbenv_ = envp;
}
// Child classes override this function to check the db and environment
// handles are correctly configured.
virtual const char* verify_config(Db* pdb, DbEnv* penv) const
{
if (pdb != NULL && ((pdb->get_create_flags() &
DB_CXX_NO_EXCEPTIONS) == 0))
return
"Db and DbEnv object must be constructed with DB_CXX_NO_EXCEPTIONS flag set.";
if (penv != NULL && ((penv->get_create_flags() &
DB_CXX_NO_EXCEPTIONS) == 0))
return
"Db and DbEnv object must be constructed with DB_CXX_NO_EXCEPTIONS flag set.";
return NULL;
}
// Use db and dbenv_ to determine whether to enable autocommit. If
// DB_AUTOCOMMIT is set on dbenv_ or db and dbenv_ is transactional,
// that db should be autocommit.
//
void set_auto_commit(Db* db);
// Begin a transaction. Used to make a container's db related
// operations auto commit when the operation completes and abort
// when the operation fails. If there is already a transaction for this
// container's environment, then that transaction is used. If the
// transaction was created by DB STL, its reference count is
// incremented (user created and external transactions are not
// reference counted because they can be nested.).
inline DbTxn* begin_txn() const
{
DbTxn *txn = NULL;
if (this->auto_commit_) {
txn = ResourceManager::instance()->begin_txn(
this->txn_begin_flags_, dbenv_, 0);
}
return txn;
}
inline void commit_txn() const
{
if (this->auto_commit_) {
ResourceManager::instance()->
commit_txn(pdb_->get_env(), this->commit_flags_);
}
}
inline void abort_txn() const
{
if (this->auto_commit_)
ResourceManager::instance()->
abort_txn(pdb_->get_env());
}
inline DbTxn *current_txn() const
{
return ResourceManager::instance()->
current_txn(pdb_->get_env());
}
}; // db_container
/** @} */ // dbstl_containers
/// \addtogroup dbstl_helper_classes
//@{
/// Bulk retrieval configuration helper class. Used by the begin() function of
/// a container.
class _exported BulkRetrievalOption
{
public:
enum Option {BulkRetrieval, NoBulkRetrieval};
protected:
Option bulk_retrieve;
u_int32_t bulk_buf_sz_;
inline BulkRetrievalOption()
{
bulk_retrieve = NoBulkRetrieval;
bulk_buf_sz_ = DBSTL_BULK_BUF_SIZE;
}
public:
inline BulkRetrievalOption(Option bulk_retrieve1,
u_int32_t bulk_buf_sz = DBSTL_BULK_BUF_SIZE)
{
this->bulk_retrieve = bulk_retrieve1;
this->bulk_buf_sz_ = bulk_buf_sz;
}
// The following two static members should best be const, but this is
// impossible because in C++ this definition is a function declaration:
// const static BulkRetrievalOption BulkRetrieval(BulkRetrieval);
// i.e. const static members can only be inited with default copy
// constructor.
//
// Static data members can't be compiled into a .lib for a dll on
// Windows, code using the static members will have link error---
// unresolved symbols, so we have to use a static function here.
/// This function indicates that you need a bulk retrieval iterator,
/// and it can be also used to optionally set the bulk read buffer size.
inline static BulkRetrievalOption bulk_retrieval(
u_int32_t bulk_buf_sz = DBSTL_BULK_BUF_SIZE)
{
return BulkRetrievalOption(BulkRetrieval, bulk_buf_sz);
}
/// This function indicates that you do not need a bulk retrieval
/// iterator.
inline static BulkRetrievalOption no_bulk_retrieval()
{
return BulkRetrievalOption(NoBulkRetrieval, 0);
}
/// Equality comparison.
inline bool operator==(const BulkRetrievalOption& bro) const
{
return bulk_retrieve == bro.bulk_retrieve;
}
/// Assignment operator.
inline void operator=(BulkRetrievalOption::Option opt)
{
bulk_retrieve = opt;
}
/// Return the buffer size set to this object.
inline u_int32_t bulk_buf_size()
{
return bulk_buf_sz_;
}
};
//@}
/// \addtogroup dbstl_helper_classes
//@{
/// Read-modify-write cursor configuration helper class. Used by each begin()
/// function of all containers.
class _exported ReadModifyWriteOption
{
protected:
enum Option{ReadModifyWrite, NoReadModifyWrite};
Option rmw;
inline ReadModifyWriteOption(Option rmw1)
{
this->rmw = rmw1;
}
inline ReadModifyWriteOption()
{
rmw = NoReadModifyWrite;
}
public:
/// Assignment operator.
inline void operator=(ReadModifyWriteOption::Option rmw1)
{
this->rmw = rmw1;
}
/// Equality comparison.
inline bool operator==(const ReadModifyWriteOption &rmw1) const
{
return this->rmw == rmw1.rmw;
}
/// Call this function to tell the container's begin() function that
/// you need a read-modify-write iterator.
inline static ReadModifyWriteOption read_modify_write()
{
return ReadModifyWriteOption(ReadModifyWrite);
}
/// Call this function to tell the container's begin() function that
/// you do not need a read-modify-write iterator. This is the default
/// value for the parameter of any container's begin() function.
inline static ReadModifyWriteOption no_read_modify_write()
{
return ReadModifyWriteOption(NoReadModifyWrite);
}
};
//@} // dbstl_helper_classes
// The classes in the Berkeley DB C++ API do not expose data and p_ member.
// Extend the class to provide this functionality, rather than altering the
// internal implementations.
//
class _exported DbstlMultipleIterator : protected DbMultipleIterator
{
protected:
DbstlMultipleIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {}
public:
u_int32_t get_pointer()
{
u_int32_t off;
off = (u_int32_t)((u_int8_t*)p_ - data_);
return off;
}
inline void set_pointer(u_int32_t offset)
{
p_ = (u_int32_t*)(data_ + offset);
}
};
class _exported DbstlMultipleKeyDataIterator : public DbstlMultipleIterator
{
public:
DbstlMultipleKeyDataIterator(const Dbt &dbt)
: DbstlMultipleIterator(dbt) {}
bool next(Dbt &key, Dbt &data);
};
class _exported DbstlMultipleRecnoDataIterator : public DbstlMultipleIterator
{
public:
DbstlMultipleRecnoDataIterator(const Dbt &dbt)
: DbstlMultipleIterator(dbt) {}
bool next(db_recno_t &recno, Dbt &data);
};
class _exported DbstlMultipleDataIterator : public DbstlMultipleIterator
{
public:
DbstlMultipleDataIterator(const Dbt &dbt)
: DbstlMultipleIterator(dbt) {}
bool next(Dbt &data);
};
// These classes are used to give data values meaningful default
// initializations. They are only necessary for types that do not have a
// reasonable default constructor - explicitly char *, wchar_t * and T*.
// The string types don't have a reasonable default initializer since we store
// the underlying content, not a pointer.
// So we fully instantiate types for T* and const T* and set the pointers to
// NULL and leave other types intact.
template <Typename T>
class DbstlInitializeDefault
{
public:
DbstlInitializeDefault(T&){}
};
template <Typename T>
class DbstlInitializeDefault<T *>
{
public:
DbstlInitializeDefault(T *& t){t = NULL;}
};
template <Typename T>
class DbstlInitializeDefault<const T *>
{
public:
DbstlInitializeDefault(const T *& t){t = NULL;}
};
END_NS
#endif //_DB_STL_CONTAINER_H__
|