Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F10907476
db.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Subscribers
None
db.h
View Options
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_DB_H
#define BITCOIN_DB_H
#include
"serialize.h"
#include
"sync.h"
#include
"version.h"
#include
<map>
#include
<string>
#include
<vector>
#include
<boost/filesystem/path.hpp>
#include
<db_cxx.h>
class
CAddrMan
;
struct
CBlockLocator
;
class
CDiskBlockIndex
;
class
COutPoint
;
extern
unsigned
int
nWalletDBUpdated
;
void
ThreadFlushWalletDB
(
const
std
::
string
&
strWalletFile
);
class
CDBEnv
{
private
:
bool
fDbEnvInit
;
bool
fMockDb
;
boost
::
filesystem
::
path
path
;
void
EnvShutdown
();
public
:
mutable
CCriticalSection
cs_db
;
DbEnv
dbenv
;
std
::
map
<
std
::
string
,
int
>
mapFileUseCount
;
std
::
map
<
std
::
string
,
Db
*>
mapDb
;
CDBEnv
();
~
CDBEnv
();
void
MakeMock
();
bool
IsMock
()
{
return
fMockDb
;
}
/*
* Verify that database file strFile is OK. If it is not,
* call the callback to try to recover.
* This must be called BEFORE strFile is opened.
* Returns true if strFile is OK.
*/
enum
VerifyResult
{
VERIFY_OK
,
RECOVER_OK
,
RECOVER_FAIL
};
VerifyResult
Verify
(
std
::
string
strFile
,
bool
(
*
recoverFunc
)(
CDBEnv
&
dbenv
,
std
::
string
strFile
));
/*
* Salvage data from a file that Verify says is bad.
* fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation).
* Appends binary key/value pairs to vResult, returns true if successful.
* NOTE: reads the entire database into memory, so cannot be used
* for huge databases.
*/
typedef
std
::
pair
<
std
::
vector
<
unsigned
char
>
,
std
::
vector
<
unsigned
char
>
>
KeyValPair
;
bool
Salvage
(
std
::
string
strFile
,
bool
fAggressive
,
std
::
vector
<
KeyValPair
>&
vResult
);
bool
Open
(
const
boost
::
filesystem
::
path
&
path
);
void
Close
();
void
Flush
(
bool
fShutdown
);
void
CheckpointLSN
(
std
::
string
strFile
);
void
CloseDb
(
const
std
::
string
&
strFile
);
bool
RemoveDb
(
const
std
::
string
&
strFile
);
DbTxn
*
TxnBegin
(
int
flags
=
DB_TXN_WRITE_NOSYNC
)
{
DbTxn
*
ptxn
=
NULL
;
int
ret
=
dbenv
.
txn_begin
(
NULL
,
&
ptxn
,
flags
);
if
(
!
ptxn
||
ret
!=
0
)
return
NULL
;
return
ptxn
;
}
};
extern
CDBEnv
bitdb
;
/** RAII class that provides access to a Berkeley database */
class
CDB
{
protected
:
Db
*
pdb
;
std
::
string
strFile
;
DbTxn
*
activeTxn
;
bool
fReadOnly
;
explicit
CDB
(
const
char
*
pszFile
,
const
char
*
pszMode
=
"r+"
);
~
CDB
()
{
Close
();
}
public
:
void
Flush
();
void
Close
();
private
:
CDB
(
const
CDB
&
);
void
operator
=
(
const
CDB
&
);
protected
:
template
<
typename
K
,
typename
T
>
bool
Read
(
const
K
&
key
,
T
&
value
)
{
if
(
!
pdb
)
return
false
;
// Key
CDataStream
ssKey
(
SER_DISK
,
CLIENT_VERSION
);
ssKey
.
reserve
(
1000
);
ssKey
<<
key
;
Dbt
datKey
(
&
ssKey
[
0
],
ssKey
.
size
());
// Read
Dbt
datValue
;
datValue
.
set_flags
(
DB_DBT_MALLOC
);
int
ret
=
pdb
->
get
(
activeTxn
,
&
datKey
,
&
datValue
,
0
);
memset
(
datKey
.
get_data
(),
0
,
datKey
.
get_size
());
if
(
datValue
.
get_data
()
==
NULL
)
return
false
;
// Unserialize value
try
{
CDataStream
ssValue
((
char
*
)
datValue
.
get_data
(),
(
char
*
)
datValue
.
get_data
()
+
datValue
.
get_size
(),
SER_DISK
,
CLIENT_VERSION
);
ssValue
>>
value
;
}
catch
(
std
::
exception
&
e
)
{
return
false
;
}
// Clear and free memory
memset
(
datValue
.
get_data
(),
0
,
datValue
.
get_size
());
free
(
datValue
.
get_data
());
return
(
ret
==
0
);
}
template
<
typename
K
,
typename
T
>
bool
Write
(
const
K
&
key
,
const
T
&
value
,
bool
fOverwrite
=
true
)
{
if
(
!
pdb
)
return
false
;
if
(
fReadOnly
)
assert
(
!
"Write called on database in read-only mode"
);
// Key
CDataStream
ssKey
(
SER_DISK
,
CLIENT_VERSION
);
ssKey
.
reserve
(
1000
);
ssKey
<<
key
;
Dbt
datKey
(
&
ssKey
[
0
],
ssKey
.
size
());
// Value
CDataStream
ssValue
(
SER_DISK
,
CLIENT_VERSION
);
ssValue
.
reserve
(
10000
);
ssValue
<<
value
;
Dbt
datValue
(
&
ssValue
[
0
],
ssValue
.
size
());
// Write
int
ret
=
pdb
->
put
(
activeTxn
,
&
datKey
,
&
datValue
,
(
fOverwrite
?
0
:
DB_NOOVERWRITE
));
// Clear memory in case it was a private key
memset
(
datKey
.
get_data
(),
0
,
datKey
.
get_size
());
memset
(
datValue
.
get_data
(),
0
,
datValue
.
get_size
());
return
(
ret
==
0
);
}
template
<
typename
K
>
bool
Erase
(
const
K
&
key
)
{
if
(
!
pdb
)
return
false
;
if
(
fReadOnly
)
assert
(
!
"Erase called on database in read-only mode"
);
// Key
CDataStream
ssKey
(
SER_DISK
,
CLIENT_VERSION
);
ssKey
.
reserve
(
1000
);
ssKey
<<
key
;
Dbt
datKey
(
&
ssKey
[
0
],
ssKey
.
size
());
// Erase
int
ret
=
pdb
->
del
(
activeTxn
,
&
datKey
,
0
);
// Clear memory
memset
(
datKey
.
get_data
(),
0
,
datKey
.
get_size
());
return
(
ret
==
0
||
ret
==
DB_NOTFOUND
);
}
template
<
typename
K
>
bool
Exists
(
const
K
&
key
)
{
if
(
!
pdb
)
return
false
;
// Key
CDataStream
ssKey
(
SER_DISK
,
CLIENT_VERSION
);
ssKey
.
reserve
(
1000
);
ssKey
<<
key
;
Dbt
datKey
(
&
ssKey
[
0
],
ssKey
.
size
());
// Exists
int
ret
=
pdb
->
exists
(
activeTxn
,
&
datKey
,
0
);
// Clear memory
memset
(
datKey
.
get_data
(),
0
,
datKey
.
get_size
());
return
(
ret
==
0
);
}
Dbc
*
GetCursor
()
{
if
(
!
pdb
)
return
NULL
;
Dbc
*
pcursor
=
NULL
;
int
ret
=
pdb
->
cursor
(
NULL
,
&
pcursor
,
0
);
if
(
ret
!=
0
)
return
NULL
;
return
pcursor
;
}
int
ReadAtCursor
(
Dbc
*
pcursor
,
CDataStream
&
ssKey
,
CDataStream
&
ssValue
,
unsigned
int
fFlags
=
DB_NEXT
)
{
// Read at cursor
Dbt
datKey
;
if
(
fFlags
==
DB_SET
||
fFlags
==
DB_SET_RANGE
||
fFlags
==
DB_GET_BOTH
||
fFlags
==
DB_GET_BOTH_RANGE
)
{
datKey
.
set_data
(
&
ssKey
[
0
]);
datKey
.
set_size
(
ssKey
.
size
());
}
Dbt
datValue
;
if
(
fFlags
==
DB_GET_BOTH
||
fFlags
==
DB_GET_BOTH_RANGE
)
{
datValue
.
set_data
(
&
ssValue
[
0
]);
datValue
.
set_size
(
ssValue
.
size
());
}
datKey
.
set_flags
(
DB_DBT_MALLOC
);
datValue
.
set_flags
(
DB_DBT_MALLOC
);
int
ret
=
pcursor
->
get
(
&
datKey
,
&
datValue
,
fFlags
);
if
(
ret
!=
0
)
return
ret
;
else
if
(
datKey
.
get_data
()
==
NULL
||
datValue
.
get_data
()
==
NULL
)
return
99999
;
// Convert to streams
ssKey
.
SetType
(
SER_DISK
);
ssKey
.
clear
();
ssKey
.
write
((
char
*
)
datKey
.
get_data
(),
datKey
.
get_size
());
ssValue
.
SetType
(
SER_DISK
);
ssValue
.
clear
();
ssValue
.
write
((
char
*
)
datValue
.
get_data
(),
datValue
.
get_size
());
// Clear and free memory
memset
(
datKey
.
get_data
(),
0
,
datKey
.
get_size
());
memset
(
datValue
.
get_data
(),
0
,
datValue
.
get_size
());
free
(
datKey
.
get_data
());
free
(
datValue
.
get_data
());
return
0
;
}
public
:
bool
TxnBegin
()
{
if
(
!
pdb
||
activeTxn
)
return
false
;
DbTxn
*
ptxn
=
bitdb
.
TxnBegin
();
if
(
!
ptxn
)
return
false
;
activeTxn
=
ptxn
;
return
true
;
}
bool
TxnCommit
()
{
if
(
!
pdb
||
!
activeTxn
)
return
false
;
int
ret
=
activeTxn
->
commit
(
0
);
activeTxn
=
NULL
;
return
(
ret
==
0
);
}
bool
TxnAbort
()
{
if
(
!
pdb
||
!
activeTxn
)
return
false
;
int
ret
=
activeTxn
->
abort
();
activeTxn
=
NULL
;
return
(
ret
==
0
);
}
bool
ReadVersion
(
int
&
nVersion
)
{
nVersion
=
0
;
return
Read
(
std
::
string
(
"version"
),
nVersion
);
}
bool
WriteVersion
(
int
nVersion
)
{
return
Write
(
std
::
string
(
"version"
),
nVersion
);
}
bool
static
Rewrite
(
const
std
::
string
&
strFile
,
const
char
*
pszSkip
=
NULL
);
};
#endif
// BITCOIN_DB_H
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Mon, Nov 25, 07:57 (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4514337
Default Alt Text
db.h (8 KB)
Attached To
rABC Bitcoin ABC
Event Timeline
Log In to Comment