flightaware / speedtables

Speed tables is a high-performance memory-resident database. The speed table compiler reads a table definition and generates a set of C access routines to create, manipulate and search tables containing millions of rows. Currently oriented towards Tcl.
https://flightaware.github.io/speedtables/
BSD 3-Clause "New" or "Revised" License
66 stars 15 forks source link

Shared memory speed tables will lose columns when more than one table is created #10

Closed bovine closed 12 years ago

bovine commented 13 years ago

When more than one shared-memory speedtable is created in a process, data starts getting lost from the inserted rows. Here is a sample program:

#!/usr/local/bin/tclsh8.5

package require Tclx
package require speedtable

CExtension bullseye 1.0 {
    CTable Pasture {
        varstring alpha
        varstring beta indexed 1
        varstring delta
        varstring gamma indexed 1
    }

    CTable Barn {
        varstring alpha
        varstring beta
        varstring delta
        varstring gamma
    }
}

package require Bullseye

if {$argv == 1} {
    puts "using shmem"
    Pasture create mypasture master name "moo3" file "mypasture.dat" size "256M"
    Barn create mybarn master name "moo4" file "mybarn.dat" size "256M"
} else {
    puts "using mem"
    Pasture create mypasture
    Barn create mybarn
}

puts "created"

for {set i 0} {$i < 10000} {incr i} {
    mypasture store [list alpha alfa$i beta bravo$i delta delta$i gamma golf$i]

    if {$i % 150 == 0} {
        mybarn store [list alpha alfa$i beta bravo$i delta delta$i gamma golf$i]
    }
}

puts "inserted"

mybarn search -array barnrow -limit 10 -sort alpha -code {
    set count [array size barnrow]
    if {$count != 5} {
        puts "Error: wrong number of elements (was $count, expected 5)"
    }
    parray barnrow
    puts ""
}

puts info=[mypasture share info]
puts pools=[mypasture share pools]
puts free=[mypasture share free]

Run it with argument of 0 and it will work:

$ ./shmemtwo.tcl 0
using mem
created
inserted
barnrow(_key)  = 0
barnrow(alpha) = alfa0
barnrow(beta)  = bravo0
barnrow(delta) = delta0
barnrow(gamma) = golf0

barnrow(_key)  = 7
barnrow(alpha) = alfa1050
barnrow(beta)  = bravo1050
barnrow(delta) = delta1050
barnrow(gamma) = golf1050

barnrow(_key)  = 8
barnrow(alpha) = alfa1200
barnrow(beta)  = bravo1200
barnrow(delta) = delta1200
barnrow(gamma) = golf1200

barnrow(_key)  = 9
barnrow(alpha) = alfa1350
barnrow(beta)  = bravo1350
barnrow(delta) = delta1350
barnrow(gamma) = golf1350

barnrow(_key)  = 1
barnrow(alpha) = alfa150
barnrow(beta)  = bravo150
barnrow(delta) = delta150
barnrow(gamma) = golf150

barnrow(_key)  = 10
barnrow(alpha) = alfa1500
barnrow(beta)  = bravo1500
barnrow(delta) = delta1500
barnrow(gamma) = golf1500

barnrow(_key)  = 11
barnrow(alpha) = alfa1650
barnrow(beta)  = bravo1650
barnrow(delta) = delta1650
barnrow(gamma) = golf1650

barnrow(_key)  = 12
barnrow(alpha) = alfa1800
barnrow(beta)  = bravo1800
barnrow(delta) = delta1800
barnrow(gamma) = golf1800

barnrow(_key)  = 13
barnrow(alpha) = alfa1950
barnrow(beta)  = bravo1950
barnrow(delta) = delta1950
barnrow(gamma) = golf1950

barnrow(_key)  = 14
barnrow(alpha) = alfa2100
barnrow(beta)  = bravo2100
barnrow(delta) = delta2100
barnrow(gamma) = golf2100

info=
pools=
free=

Run it with 1 and it fails:

$ ./shmemtwo.tcl 1

using shmem
created
inserted
Error: wrong number of elements (was 2, expected 5)
barnrow(_key)  = 0
barnrow(gamma) = alfa0

Error: wrong number of elements (was 2, expected 5)
barnrow(_key)  = 10065
barnrow(gamma) = alfa9998

Error: wrong number of elements (was 2, expected 5)
barnrow(_key)  = 10064
barnrow(gamma) = alfa9997

Error: wrong number of elements (was 1, expected 5)
barnrow(_key) = 10063

Error: wrong number of elements (was 1, expected 5)
barnrow(_key) = 10062

Error: wrong number of elements (was 2, expected 5)
barnrow(_key)  = 10061
barnrow(gamma) = alfa9994

Error: wrong number of elements (was 2, expected 5)
barnrow(_key)  = 10060
barnrow(gamma) = alfa9993

Error: wrong number of elements (was 1, expected 5)
barnrow(_key) = 10059

Error: wrong number of elements (was 1, expected 5)
barnrow(_key) = 10058

Error: wrong number of elements (was 2, expected 5)
barnrow(_key)  = 10057
barnrow(gamma) = alfa9990

info=size 268435456 flags {core nosync shared} name moo4 creator 1 filename mybarn.dat base -1610612736
pools=128 131072 1 131004
free=248225512

bovine commented 13 years ago

Note that changing the table creation code to only create one of the two tables in shmem also allows it to work fine. It only fails when both tables are in shmem.

bovine commented 13 years ago

This is due to lack of support for multiple shared files, you have to use the same file for both structures.

Workaround is to use the same "file" argument for all tables.

Recommend adding an error if you try to initialize more than one shared memory file. Alternatively, add full support for multiple files.

lehenbauer commented 12 years ago

After commit 6eb2e96aa47838505fd978dbd84f3afc22d362d5 we have support for multiple shared files, but recommend having only a small number due to the need to have the file mapped to the same address in the master and all off the readers.