~ubuntu-branches/ubuntu/edgy/rpm/edgy

« back to all changes in this revision

Viewing changes to db/test/si005.tcl

  • Committer: Bazaar Package Importer
  • Author(s): Joey Hess
  • Date: 2002-01-22 20:56:57 UTC
  • Revision ID: james.westby@ubuntu.com-20020122205657-l74j50mr9z8ofcl5
Tags: upstream-4.0.3
ImportĀ upstreamĀ versionĀ 4.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
# See the file LICENSE for redistribution information.
 
3
#
 
4
# Copyright (c) 2001
 
5
#       Sleepycat Software.  All rights reserved.
 
6
#
 
7
# $Id: si005.tcl,v 1.1.2.1 2001/07/23 20:40:23 jbj Exp $
 
8
#
 
9
# Sindex005: Secondary index and join test.
 
10
proc sindex005 { methods {nitems 1000} {tnum 5} args } {
 
11
        source ./include.tcl
 
12
 
 
13
        # Primary method/args.
 
14
        set pmethod [lindex $methods 0]
 
15
        set pargs [convert_args $pmethod $args]
 
16
        set pomethod [convert_method $pmethod]
 
17
 
 
18
        # Sindex005 does a join within a simulated database schema
 
19
        # in which the primary index maps a record ID to a ZIP code and
 
20
        # name in the form "XXXXXname", and there are two secondaries:
 
21
        # one mapping ZIP to ID, the other mapping name to ID.
 
22
        # The primary may be of any database type;  the two secondaries
 
23
        # must be either btree or hash.
 
24
 
 
25
        # Method/args for all the secondaries.  If only one method
 
26
        # was specified, assume the same method for the two secondaries.
 
27
        set methods [lrange $methods 1 end]
 
28
        if { [llength $methods] == 0 } {
 
29
                for { set i 0 } { $i < 2 } { incr i } {
 
30
                        lappend methods $pmethod
 
31
                }
 
32
        } elseif { [llength $methods] != 2 } {
 
33
                puts "FAIL: Sindex00$tnum requires exactly two secondaries."
 
34
                return
 
35
        }
 
36
 
 
37
        set argses [convert_argses $methods $args]
 
38
        set omethods [convert_methods $methods]
 
39
 
 
40
        puts "Sindex00$tnum ($pmethod/$methods) Secondary index join test."
 
41
        env_cleanup $testdir
 
42
 
 
43
        set pname "sindex00$tnum-primary.db"
 
44
        set zipname "sindex00$tnum-zip.db"
 
45
        set namename "sindex00$tnum-name.db"
 
46
 
 
47
        # Open an environment
 
48
        # XXX if one is not supplied!
 
49
        set env [berkdb env -create -home $testdir]
 
50
        error_check_good env_open [is_valid_env $env] TRUE
 
51
 
 
52
        # Open the databases.
 
53
        set pdb [eval {berkdb_open -create -env} $env $pomethod $pargs $pname]
 
54
        error_check_good primary_open [is_valid_db $pdb] TRUE
 
55
 
 
56
        set zipdb [eval {berkdb_open -create -dup -env} $env \
 
57
            [lindex $omethods 0] [lindex $argses 0] $zipname]
 
58
        error_check_good zip_open [is_valid_db $zipdb] TRUE
 
59
        error_check_good zip_associate [$pdb associate s5_getzip $zipdb] 0
 
60
 
 
61
        set namedb [eval {berkdb_open -create -dup -env} $env \
 
62
            [lindex $omethods 1] [lindex $argses 1] $namename]
 
63
        error_check_good name_open [is_valid_db $namedb] TRUE
 
64
        error_check_good name_associate [$pdb associate s5_getname $namedb] 0
 
65
 
 
66
        puts "\tSindex00$tnum.a: Populate database with $nitems \"names\""
 
67
        s5_populate $pdb $nitems
 
68
        puts "\tSindex00$tnum.b: Perform a join on each \"name\" and \"ZIP\""
 
69
        s5_jointest $pdb $zipdb $namedb
 
70
 
 
71
        error_check_good name_close [$namedb close] 0
 
72
        error_check_good zip_close [$zipdb close] 0
 
73
        error_check_good primary_close [$pdb close] 0
 
74
        error_check_good env_close [$env close] 0
 
75
}
 
76
 
 
77
proc s5_jointest { pdb zipdb namedb } {
 
78
        set pdbc [$pdb cursor]
 
79
        error_check_good pdb_cursor [is_valid_cursor $pdbc $pdb] TRUE
 
80
        for { set dbt [$pdbc get -first] } { [llength $dbt] > 0 } \
 
81
            { set dbt [$pdbc get -next] } {
 
82
                set item [lindex [lindex $dbt 0] 1]
 
83
                set retlist [s5_dojoin $item $pdb $zipdb $namedb]
 
84
        }
 
85
}
 
86
 
 
87
proc s5_dojoin { item pdb zipdb namedb } {
 
88
        set name [s5_getname "" $item]
 
89
        set zip [s5_getzip "" $item]
 
90
 
 
91
        set zipc [$zipdb cursor]
 
92
        error_check_good zipc($item) [is_valid_cursor $zipc $zipdb] TRUE
 
93
 
 
94
        set namec [$namedb cursor]
 
95
        error_check_good namec($item) [is_valid_cursor $namec $namedb] TRUE
 
96
 
 
97
        set pc [$pdb cursor]
 
98
        error_check_good pc($item) [is_valid_cursor $pc $pdb] TRUE
 
99
 
 
100
        set ret [$zipc get -set $zip]
 
101
        set zd [lindex [lindex $ret 0] 1]
 
102
        error_check_good zipset($zip) [s5_getzip "" $zd] $zip
 
103
 
 
104
        set ret [$namec get -set $name]
 
105
        set nd [lindex [lindex $ret 0] 1]
 
106
        error_check_good nameset($name) [s5_getname "" $nd] $name
 
107
 
 
108
        set joinc [$pdb join $zipc $namec]
 
109
 
 
110
        set anyreturned 0
 
111
        for { set dbt [$joinc get] } { [llength $dbt] > 0 } \
 
112
            { set dbt [$joinc get] } {
 
113
                set ritem [lindex [lindex $dbt 0] 1]
 
114
                error_check_good returned_item($item) $ritem $item
 
115
                incr anyreturned
 
116
        }
 
117
        error_check_bad anyreturned($item) $anyreturned 0
 
118
 
 
119
        error_check_good joinc_close($item) [$joinc close] 0
 
120
        error_check_good pc_close($item) [$pc close] 0
 
121
        error_check_good namec_close($item) [$namec close] 0
 
122
        error_check_good zipc_close($item) [$zipc close] 0
 
123
}
 
124
 
 
125
proc s5_populate { db nitems } {
 
126
        global dict
 
127
 
 
128
        set did [open $dict]
 
129
        for { set i 1 } { $i <= $nitems } { incr i } {
 
130
                gets $did word
 
131
                if { [string length $word] < 3 } {
 
132
                        gets $did word
 
133
                        if { [string length $word] < 3 } {
 
134
                                puts "FAIL:\
 
135
                                    unexpected pair of words < 3 chars long"
 
136
                        }
 
137
                }
 
138
                set datalist [s5_name2zips $word]
 
139
                foreach data $datalist {
 
140
                        error_check_good db_put($data) [$db put $i $data$word] 0
 
141
                }
 
142
        }
 
143
        close $did
 
144
}
 
145
 
 
146
proc s5_getzip { key data } { return [string range $data 0 4] }
 
147
proc s5_getname { key data } { return [string range $data 5 end] }
 
148
 
 
149
# The dirty secret of this test is that the ZIP code is a function of the
 
150
# name, so we can generate a database and then verify join results easily
 
151
# without having to consult actual data.
 
152
#
 
153
# Any word passed into this function will generate from 1 to 26 ZIP
 
154
# entries, out of the set {00000, 01000 ... 99000}.  The number of entries
 
155
# is just the position in the alphabet of the word's first letter;  the
 
156
# entries are then hashed to the set {00, 01 ... 99} N different ways.
 
157
proc s5_name2zips { name } {
 
158
        global alphabet
 
159
 
 
160
        set n [expr [string first [string index $name 0] $alphabet] + 1]
 
161
        error_check_bad starts_with_abc($name) $n -1
 
162
 
 
163
        set ret {}
 
164
        for { set i 0 } { $i < $n } { incr i } {
 
165
                set b 0
 
166
                for { set j 1 } { $j < [string length $name] } \
 
167
                    { incr j } {
 
168
                        set b [s5_nhash $name $i $j $b]
 
169
                }
 
170
                lappend ret [format %05u [expr $b % 100]000]
 
171
        }
 
172
        return $ret
 
173
}
 
174
proc s5_nhash { name i j b } {
 
175
        global alphabet
 
176
 
 
177
        set c [string first [string index $name $j] $alphabet']
 
178
        return [expr (($b * 991) + ($i * 997) + $c) % 10000000]
 
179
}