]> arthur.barton.de Git - bup.git/blob - cmd/memtest-cmd.py
610e4395839c5b27ad3aa3c595bc3772bb81e1fd
[bup.git] / cmd / memtest-cmd.py
1 #!/usr/bin/env python
2 import sys, re, struct, mmap, time, resource
3 from bup import git, options
4 from bup.helpers import *
5
6 handle_ctrl_c()
7
8 def s_from_bytes(bytes):
9     clist = [chr(b) for b in bytes]
10     return ''.join(clist)
11
12
13 _linux_warned = 0
14 def linux_memstat():
15     global _linux_warned
16     #fields = ['VmSize', 'VmRSS', 'VmData', 'VmStk', 'ms']
17     d = {}
18     try:
19         f = open('/proc/self/status')
20     except IOError, e:
21         if not _linux_warned:
22             log('Warning: %s\n' % e)
23             _linux_warned = 1
24         return {}
25     for line in f:
26         k,v = re.split(r':\s*', line.strip(), 1)
27         d[k] = v
28     return d
29
30
31 last = last_u = last_s = start = 0
32 def report(count):
33     global last, last_u, last_s, start
34     headers = ['RSS', 'MajFlt', 'user', 'sys', 'ms']
35     ru = resource.getrusage(resource.RUSAGE_SELF)
36     now = time.time()
37     rss = int(ru.ru_maxrss/1024)
38     if not rss:
39         rss = linux_memstat().get('VmRSS', '??')
40     fields = [rss,
41               ru.ru_majflt,
42               int((ru.ru_utime - last_u) * 1000),
43               int((ru.ru_stime - last_s) * 1000),
44               int((now - last) * 1000)]
45     fmt = '%9s  ' + ('%10s ' * len(fields))
46     if count >= 0:
47         print fmt % tuple([count] + fields)
48     else:
49         start = now
50         print fmt % tuple([''] + headers)
51     sys.stdout.flush()
52     
53     # don't include time to run report() in usage counts
54     ru = resource.getrusage(resource.RUSAGE_SELF)
55     last_u = ru.ru_utime
56     last_s = ru.ru_stime
57     last = time.time()
58
59
60 optspec = """
61 bup memtest [-n elements] [-c cycles]
62 --
63 n,number=  number of objects per cycle [10000]
64 c,cycles=  number of cycles to run [100]
65 ignore-midx  ignore .midx files, use only .idx files
66 existing   test with existing objects instead of fake ones
67 """
68 o = options.Options('bup memtest', optspec)
69 (opt, flags, extra) = o.parse(sys.argv[1:])
70
71 if extra:
72     o.fatal('no arguments expected')
73
74 git.ignore_midx = opt.ignore_midx
75
76 git.check_repo_or_die()
77 m = git.PackIdxList(git.repo('objects/pack'))
78
79 report(-1)
80 f = open('/dev/urandom')
81 a = mmap.mmap(-1, 20)
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             b = f.read(3)
98             a[0:2] = b[0:2]
99             a[2] = chr(ord(b[2]) & 0xf0)
100             bin = str(a[0:20])
101
102             # technically, a randomly generated object id might exist.
103             # but the likelihood of that is the likelihood of finding
104             # a collision in sha-1 by accident, which is so unlikely that
105             # we don't care.
106             assert(not m.exists(bin))
107     report((c+1)*opt.number)
108
109 print ('%d objects searched in %d steps: avg %.3f steps/object' 
110        % (git._total_searches, git._total_steps,
111           git._total_steps*1.0/git._total_searches))
112 print 'Total time: %.3fs' % (time.time() - start)