1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1999,2008 Oracle.  All rights reserved.
4#
5# $Id: sdbtest002.tcl,v 12.7 2008/01/08 20:58:53 bostic Exp $
6#
7# TEST	sdbtest002
8# TEST	Tests multiple access methods in one subdb access by multiple
9# TEST	processes.
10# TEST		Open several subdbs, each with a different access method
11# TEST		Small keys, small data
12# TEST		Put/get per key per subdb
13# TEST		Fork off several child procs to each delete selected
14# TEST		    data from their subdb and then exit
15# TEST		Dump file, verify contents of each subdb is correct
16# TEST		Close, reopen per subdb
17# TEST		Dump file, verify per subdb
18# TEST
19# TEST	Make several subdb's of different access methods all in one DB.
20# TEST	Fork of some child procs to each manipulate one subdb and when
21# TEST	they are finished, verify the contents of the databases.
22# TEST	Use the first 10,000 entries from the dictionary.
23# TEST	Insert each with self as key and data; retrieve each.
24# TEST	After all are entered, retrieve all; compare output to original.
25# TEST	Close file, reopen, do retrieve and re-verify.
26proc sdbtest002 { {nentries 10000} } {
27	source ./include.tcl
28
29	puts "Subdbtest002: many different subdb access methods in one"
30
31	# Create the database and open the dictionary
32	set testfile $testdir/subdbtest002.db
33	set t1 $testdir/t1
34	set t2 $testdir/t2
35	set t3 $testdir/t3
36	set t4 $testdir/t4
37
38	set txn ""
39	set count 0
40
41	# Set up various methods to rotate through
42	set methods \
43	    [list "-rbtree" "-recno" "-btree" "-btree" "-recno" "-rbtree"]
44	cleanup $testdir NULL
45	puts "\tSubdbtest002.a: create subdbs of different methods: $methods"
46	set psize 4096
47	set nsubdbs [llength $methods]
48	set duplist ""
49	for { set i 0 } { $i < $nsubdbs } { incr i } {
50		lappend duplist -1
51	}
52	set newent [expr $nentries / $nsubdbs]
53
54	#
55	# XXX We need dict sorted to figure out what was deleted
56	# since things are stored sorted in the btree.
57	#
58	filesort $dict $t4
59	set dictorig $dict
60	set dict $t4
61
62	build_all_subdb $testfile $methods $psize $duplist $newent
63
64	# Now we will get each key from the DB and compare the results
65	# to the original.
66	set pidlist ""
67	puts "\tSubdbtest002.b: create $nsubdbs procs to delete some keys"
68	for { set subdb 0 } { $subdb < $nsubdbs } { incr subdb } {
69		puts "$tclsh_path\
70		    $test_path/sdbscript.tcl $testfile \
71		    $subdb $nsubdbs >& $testdir/subdb002.log.$subdb"
72		set p [exec $tclsh_path $test_path/wrap.tcl \
73		    sdbscript.tcl \
74		    $testdir/subdb002.log.$subdb $testfile $subdb $nsubdbs &]
75		lappend pidlist $p
76	}
77	watch_procs $pidlist 5
78
79	for { set subdb 0 } { $subdb < $nsubdbs } { incr subdb } {
80		set method [lindex $methods $subdb]
81		set method [convert_method $method]
82		if { [is_record_based $method] == 1 } {
83			set checkfunc subdbtest002_recno.check
84		} else {
85			set checkfunc subdbtest002.check
86		}
87
88		puts "\tSubdbtest002.b: dump file sub$subdb.db"
89		set db [berkdb_open -unknown $testfile sub$subdb.db]
90		error_check_good db_open [is_valid_db $db] TRUE
91		dump_file $db $txn $t1 $checkfunc
92		error_check_good db_close [$db close] 0
93
94		# Now compare the keys to see if they match the dictionary (or ints)
95		if { [is_record_based $method] == 1 } {
96			set oid [open $t2 w]
97			for {set i 1} {$i <= $newent} {incr i} {
98				set x [expr $i - $subdb]
99				if { [expr $x % $nsubdbs] != 0 } {
100					puts $oid [expr $subdb * $newent + $i]
101				}
102			}
103			close $oid
104			file rename -force $t1 $t3
105		} else {
106			set oid [open $t4 r]
107			for {set i 1} {[gets $oid line] >= 0} {incr i} {
108				set farr($i) $line
109			}
110			close $oid
111
112			set oid [open $t2 w]
113			for {set i 1} {$i <= $newent} {incr i} {
114				# Sed uses 1-based line numbers
115				set x [expr $i - $subdb]
116				if { [expr $x % $nsubdbs] != 0 } {
117					set beg [expr $subdb * $newent]
118					set beg [expr $beg + $i]
119					puts $oid $farr($beg)
120				}
121			}
122			close $oid
123			filesort $t1 $t3
124		}
125
126		error_check_good Subdbtest002:diff($t3,$t2) \
127		    [filecmp $t3 $t2] 0
128
129		puts "\tSubdbtest002.c: sub$subdb.db: close, open, and dump file"
130		# Now, reopen the file and run the last test again.
131		open_and_dump_subfile $testfile NULL $t1 $checkfunc \
132		    dump_file_direction "-first" "-next" sub$subdb.db
133		if { [string compare $method "-recno"] != 0 } {
134			filesort $t1 $t3
135		}
136
137		error_check_good Subdbtest002:diff($t2,$t3) \
138		    [filecmp $t2 $t3] 0
139
140		# Now, reopen the file and run the last test again in the
141		# reverse direction.
142		puts "\tSubdbtest002.d: sub$subdb.db: close, open, and dump file in reverse direction"
143		open_and_dump_subfile $testfile NULL $t1 $checkfunc \
144		    dump_file_direction "-last" "-prev" sub$subdb.db
145
146		if { [string compare $method "-recno"] != 0 } {
147			filesort $t1 $t3
148		}
149
150		error_check_good Subdbtest002:diff($t3,$t2) \
151		    [filecmp $t3 $t2] 0
152	}
153	set dict $dictorig
154	return
155}
156
157# Check function for Subdbtest002; keys and data are identical
158proc subdbtest002.check { key data } {
159	error_check_good "key/data mismatch" $data $key
160}
161
162proc subdbtest002_recno.check { key data } {
163global dict
164global kvals
165	error_check_good key"$key"_exists [info exists kvals($key)] 1
166	error_check_good "key/data mismatch, key $key" $data $kvals($key)
167}
168