summaryrefslogtreecommitdiff
path: root/lib/tdb2/doc/TDB1_porting.txt
blob: e59295c22f840d67972bed449adf94d25a36d5b3 (plain)
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
Interface differences between TDB1 and TDB2.

- tdb2 uses 'struct tdb_data', tdb1 uses 'struct TDB_DATA'.  Use the
  TDB_DATA typedef if you want portability between the two.

- tdb2 functions return 0 on success, and a negative error on failure,
  whereas tdb1 functions returned 0 on success, and -1 on failure.
  tdb1 then used tdb_error() to determine the error; this is also
  supported in tdb2 to ease backwards compatibility, though the other
  form is preferred.

- tdb2's tdb_fetch() returns an error, tdb1's returned the data directly
  (or tdb_null, and you were supposed to check tdb_error() to find out why).

- tdb2's tdb_nextkey() frees the old key's dptr, in tdb1 you needed to do
  this manually.

- tdb1's tdb_open/tdb_open_ex took an explicit hash size.  tdb2's hash table
  resizes as required.

- tdb2 uses a linked list of attribute structures to implement logging and
  alternate hashes.  tdb1 used tdb_open_ex, which was not extensible.

- tdb2 does locking on read-only databases (ie. O_RDONLY passed to tdb_open).
  tdb1 did not: use the TDB_NOLOCK flag if you want to suppress locking.

- tdb2's log function is simpler than tdb1's log function.  The string is
  already formatted, and it takes an enum tdb_log_level not a tdb_debug_level,
  and which has only three values: TDB_LOG_ERROR, TDB_LOG_USE_ERROR and
  TDB_LOG_WARNING.

- tdb2 provides tdb_deq() for comparing two struct tdb_data.

- tdb2's tdb_name() returns a copy of the name even for TDB_INTERNAL dbs.

- tdb2 does not need tdb_reopen() or tdb_reopen_all().  If you call
  fork() after during certain operations the child should close the
  tdb, or complete the operations before continuing to use the tdb:

	tdb_transaction_start(): child must tdb_transaction_cancel()
	tdb_lockall(): child must call tdb_unlockall()
	tdb_lockall_read(): child must call tdb_unlockall_read()
	tdb_chainlock(): child must call tdb_chainunlock()
	tdb_parse() callback: child must return from tdb_parse()

- tdb2 will not open a non-tdb file, even if O_CREAT is specified.

- There is no tdb_traverse_read.  For operating on TDB1 files, you can
  simulate it by tdb_add_flag(tdb, TDB_RDONLY); tdb_traverse();
  tdb_remove_flag(tdb, TDB_RDONLY).  This may be desirable because
  traverse on TDB1 files use a write lock on the entire database
  unless it's read-only.

- Failure inside a transaction (such as a lock function failing) does
  not implicitly cancel the transaction; you still need to call
  tdb_transaction_cancel().

TDB1 Compatibility:

- tdb2's offers a tdb1_incompatible_hash function, which is the same
  as the default hash with the TDB_INCOMPATIBLE_HASH flag.  There is
  no way of marking an old TDB incompatible with versions < 1.2.6
  while using any other hash.

- The TDB_ATTRIBUTE_TDB1_HASHSIZE attribute can be used to control the
  hash size, but only when creating (ie. O_CREAT) a TDB1
  (ie. TDB_VERSION1).

- There is no TDB_CLEAR_IF_FIRST flag; it has severe scalability and
  API problems.  If necessary, you can emulate this by using the open
  hook and placing a 1-byte lock at offset 4.  If your program forks,
  you will need to place this lock again in the child.