]> arthur.barton.de Git - bup.git/blob - cmd/memtest-cmd.py
0e3cf0c839d6a86402685a8589a0e5c6acf5b1b9
[bup.git] / cmd / memtest-cmd.py
1 #!/usr/bin/env python
2 import sys, re, struct, time, resource
3 from bup import git, bloom, midx, options, _helpers
4 from bup.helpers import *
5
6 handle_ctrl_c()
7
8 _linux_warned = 0
9 def linux_memstat():
10     global _linux_warned
11     #fields = ['VmSize', 'VmRSS', 'VmData', 'VmStk', 'ms']
12     d = {}
13     try:
14         f = open('/proc/self/status')
15     except IOError, e:
16         if not _linux_warned:
17             log('Warning: %s\n' % e)
18             _linux_warned = 1
19         return {}
20     for line in f:
21         # Note that on Solaris, this file exists but is binary.  If that
22         # happens, this split() might not return two elements.  We don't
23         # really need to care about the binary format since this output
24         # isn't used for much and report() can deal with missing entries.
25         t = re.split(r':\s*', line.strip(), 1)
26         if len(t) == 2:
27             k,v = t
28             d[k] = v
29     return d
30
31
32 last = last_u = last_s = start = 0
33 def report(count):
34     global last, last_u, last_s, start
35     headers = ['RSS', 'MajFlt', 'user', 'sys', 'ms']
36     ru = resource.getrusage(resource.RUSAGE_SELF)
37     now = time.time()
38     rss = int(ru.ru_maxrss/1024)
39     if not rss:
40         rss = linux_memstat().get('VmRSS', '??')
41     fields = [rss,
42               ru.ru_majflt,
43               int((ru.ru_utime - last_u) * 1000),
44               int((ru.ru_stime - last_s) * 1000),
45               int((now - last) * 1000)]
46     fmt = '%9s  ' + ('%10s ' * len(fields))
47     if count >= 0:
48         print fmt % tuple([count] + fields)
49     else:
50         start = now
51         print fmt % tuple([''] + headers)
52     sys.stdout.flush()
53     
54     # don't include time to run report() in usage counts
55     ru = resource.getrusage(resource.RUSAGE_SELF)
56     last_u = ru.ru_utime
57     last_s = ru.ru_stime
58     last = time.time()
59
60
61 optspec = """
62 bup memtest [-n elements] [-c cycles]
63 --
64 n,number=  number of objects per cycle [10000]
65 c,cycles=  number of cycles to run [100]
66 ignore-midx  ignore .midx files, use only .idx files
67 existing   test with existing objects instead of fake ones
68 """
69 o = options.Options(optspec)
70 (opt, flags, extra) = o.parse(sys.argv[1:])
71
72 if extra:
73     o.fatal('no arguments expected')
74
75 git.ignore_midx = opt.ignore_midx
76
77 git.check_repo_or_die()
78 m = git.PackIdxList(git.repo('objects/pack'))
79
80 report(-1)
81 _helpers.random_sha()
82 report(0)
83
84 if opt.existing:
85     def foreverit(mi):
86         while 1:
87             for e in mi:
88                 yield e
89     objit = iter(foreverit(m))
90     
91 for c in xrange(opt.cycles):
92     for n in xrange(opt.number):
93         if opt.existing:
94             bin = objit.next()
95             assert(m.exists(bin))
96         else:
97             bin = _helpers.random_sha()
98
99             # technically, a randomly generated object id might exist.
100             # but the likelihood of that is the likelihood of finding
101             # a collision in sha-1 by accident, which is so unlikely that
102             # we don't care.
103             assert(not m.exists(bin))
104     report((c+1)*opt.number)
105
106 if bloom._total_searches:
107     print ('bloom: %d objects searched in %d steps: avg %.3f steps/object' 
108            % (bloom._total_searches, bloom._total_steps,
109               bloom._total_steps*1.0/bloom._total_searches))
110 if midx._total_searches:
111     print ('midx: %d objects searched in %d steps: avg %.3f steps/object' 
112            % (midx._total_searches, midx._total_steps,
113               midx._total_steps*1.0/midx._total_searches))
114 if git._total_searches:
115     print ('idx: %d objects searched in %d steps: avg %.3f steps/object' 
116            % (git._total_searches, git._total_steps,
117               git._total_steps*1.0/git._total_searches))
118 print 'Total time: %.3fs' % (time.time() - start)