-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathreadLSM
More file actions
executable file
·136 lines (121 loc) · 3.65 KB
/
readLSM
File metadata and controls
executable file
·136 lines (121 loc) · 3.65 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/tclsh
#
# An utility to read LSM files and display their technical content.
# Slow as hell.
proc fail {msg} {
puts $msg
exit 1
}
if {[llength $argv] != 1} {
fail "usage: readLSM LSMfile"
}
proc read_at_byte_ofs {h byte_ofs count} {
seek $h $byte_ofs start
binary scan [read $h $count] c* bytes
return $bytes
}
proc read_abs_pages {h page_index pages_count} {
return [read_at_byte_ofs $h [expr $page_index << $::page_bits] [expr $pages_count << $::page_bits]]
}
proc read_log_pages {h page_index pages_count} {
return [read_abs_pages $h [expr $page_index + $::page_index_after_states] $pages_count
}
proc read_wide_int {bufvar} {
upvar $bufvar buf
set b0 [expr [lindex $buf 0] & 0xff]
set buf [lrange $buf 1 end]
if {$b0 < 236} { return $b0 }
if {$b0 < 244} {
set b1 [lindex $buf 0]
set buf [lrange $buf 1 end]
return [expr ($b0-236)+256+$b1+236]
}
if {$b0 == 244} {
set b1 [lindex $buf 0]
set b2 [lindex $buf 1]
set buf [lrange $buf 2 end]
return [expr 256*8+236+$b1*256+$b2]
}
fail "byte '$b0'??"
}
set page_bits -1
set page_size -1
set version -1
set states_count -1
set states_rec_size -1
set page_index_after_states -1
proc read_header {h} {
set buf [read_at_byte_ofs $h 0 256]
set ::version [read_wide_int buf]
set ::page_bits [read_wide_int buf]
set ::states_count [read_wide_int buf]
set ::states_rec_size [read_wide_int buf]
set ::page_size [expr 1 << $::page_bits]
puts "header: version $::version; page bits $::page_bits ($::page_size bytes); num of states $::states_count; states record size $::states_rec_size"
if {($::states_rec_size % $::page_size) != 0} {
fail "state record size ($::states_rec_size) is not divisible by page size ($::page_size)."
}
if {$::page_size < 32} {
fail "page size ($::page_size) is too small."
}
set ::page_index_after_states [expr $::states_count*$::states_rec_size/$::page_size+1]
puts "first logical page $::page_index_after_states."
}
proc read_list {bytes reader} {
upvar $bytes buf
set count [read_wide_int buf]
set elems {}
while {$count > 0} {
set elem [eval $reader buf]
lappend elems $elem
incr count -1
}
return $elems
}
proc read_block {buf} {
upvar $buf bytes
set addr [read_wide_int bytes]
set size [read_wide_int bytes]
return [dict create addr $addr size $size]
}
proc read_lsm_run {buf} {
upvar $buf bytes
set run_type [read_wide_int bytes]
set blocks [read_list bytes read_block]
return [dict create run_type $run_type blocks $blocks]
}
proc read_lsm_level {buf} {
upvar $buf bytes
set pairs_count [read_wide_int bytes]
set keys_size [read_wide_int bytes]
set data_size [read_wide_int bytes]
set runs [read_list bytes read_lsm_run]
return [dict create pairs_count $pairs_count keys_size $keys_size data_size $data_size runs $runs]
}
set states {}
set states_by_seqid {}
proc read_states {h} {
set min_seq_index -1
for {set i 0} {$i < $::states_count} {incr i} {
set bytes [read_abs_pages $h [expr ($i*$::states_rec_size / $::page_size)+1] [expr $::states_rec_size >> $::page_bits]]
set seq_index [read_wide_int bytes]
set levels [read_list bytes read_lsm_level]
if {$i == 0 || $seq_index < $min_seq_index} { set min_seq_index $seq_index }
lappend ::states [dict create seq_index $seq_index phys_index $i levels $levels]
}
puts "states: $::states"
while {[llength $::states_by_seqid] < [llength $::states]} {
set search_id [expr $min_seq_index + [llength $::states_by_seqid]]
foreach s $::states {
if {[dict get $s seq_index] == $search_id} break
}
lappend ::states_by_seqid $s
}
}
proc read_most_recent_data {h} {
}
set h [open [lindex $argv 0]]
fconfigure $h -encoding binary -translation binary
read_header $h
read_states $h
read_most_recent_data $h