wscript 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #! /usr/bin/env python
  2. """
  3. You will need either bzip2 or gzip, and a local waf copy
  4. (unset the variable WAFDIR if set)
  5. Using more than 100000 tasks may eat your memory
  6. """
  7. top = '.'
  8. out = 'build'
  9. TEMPLATE = """
  10. #! /usr/bin/gnuplot -persist
  11. # output file, compression type, input file
  12. set terminal png
  13. set output "%s"
  14. set ylabel "Amount of files created"
  15. set xlabel "File size in kB"
  16. set title "Compressed tar file distribution (%s)"
  17. plot '%s' using 1:2 with lines lt 3 title ""
  18. """
  19. import random, bz2, os, threading
  20. lock = threading.Lock()
  21. def options(opt):
  22. opt.add_option('--num', action='store', type='int', default=200, help='amount of compressed files to create')
  23. # values for storing the min and max
  24. gzip = [10000000, 0]
  25. bzip2 = [10000000, 0]
  26. xz = [10000000, 0]
  27. def try_compress(self):
  28. global mi, ma
  29. frompath = self.generator.frompath
  30. uid = id(threading.current_thread())
  31. filename = frompath.abspath() + os.sep + 'test%d.bin' % uid
  32. self.files = self.generator.files[:]
  33. random.shuffle(self.files)
  34. if self.generator.kind == 'bzip2':
  35. store = bzip2
  36. cmd = 'cjf'
  37. ext = 'bz2'
  38. elif self.generator.kind == 'xz':
  39. store = xz
  40. cmd = 'cJf'
  41. ext = 'xz'
  42. else:
  43. store = gzip
  44. cmd = 'czf'
  45. ext = 'gz'
  46. self.generator.bld.exec_command('tar %s %s %s' % (cmd, filename, ' '.join(self.files)), cwd=frompath.abspath())
  47. siz = os.stat(filename).st_size
  48. if siz == 0:
  49. return -1
  50. try:
  51. lock.acquire()
  52. self.outputs[0].write('%d\n' % siz, 'a')
  53. if siz < store[0]:
  54. store[0] = siz
  55. os.rename(filename, self.generator.bld.bldnode.abspath() + os.sep + 'min%d.tar.%s' % (siz, ext))
  56. elif siz > store[1]:
  57. store[1] = siz
  58. os.rename(filename, self.generator.bld.bldnode.abspath() + os.sep + 'max%d.tar.%s' % (siz, ext))
  59. else:
  60. os.remove(filename)
  61. finally:
  62. lock.release()
  63. def count_result(self):
  64. txt = self.inputs[0].read().strip()
  65. lst = txt.split()
  66. lst = [int(x) for x in lst if x]
  67. mi = min(lst)
  68. ma = max(lst)
  69. dc = {}
  70. for x in lst:
  71. try:
  72. dc[x] += 1
  73. except KeyError:
  74. dc[x] = 1
  75. nlst = ['%d %d' % (x, dc.get(x, 0)) for x in range(mi, ma+1)]
  76. self.outputs[0].write('\n'.join(nlst))
  77. def write_template(self):
  78. t = self.generator.triplet
  79. self.outputs[0].write(TEMPLATE % (t[0].abspath(), t[1], t[2].abspath()))
  80. def configure(conf):
  81. conf.find_program('gzip', mandatory=False)
  82. conf.find_program('bzip2', mandatory=False)
  83. if not conf.env.GZIP and not conf.env.BZIP2:
  84. conf.fatal('Either gzip or bzip2 is necessary for this')
  85. # xz is a gzip-like, lzma-based compression tool
  86. conf.find_program('xz', mandatory=False)
  87. conf.find_program('gnuplot', var='GNUPLOT')
  88. def build(bld):
  89. wafdir_lst = bld.srcnode.ant_glob('.waf*', dir=True)
  90. if not wafdir_lst:
  91. bld.fatal('Missing local Waf directory')
  92. node = wafdir_lst[0]
  93. rels = [x.path_from(node) for x in node.ant_glob('**/*.py')]
  94. KINDS = []
  95. if bld.env.BZIP2:
  96. KINDS.append('bzip2')
  97. if bld.env.GZIP:
  98. KINDS.append('gzip')
  99. if bld.env.XZ:
  100. KINDS.append('xz')
  101. for kind in KINDS:
  102. p = bld.bldnode
  103. ini = p.make_node('size_%s_1.txt' % kind) # list of file sizes
  104. dist = p.make_node('size_%s_2.txt' % kind) # distribution file (count the results)
  105. plot = p.make_node('size_%s_3.plot' % kind) # script file created for gnuplot
  106. png = p.make_node('size_%s_4.png' % kind) # picture created
  107. for x in range(bld.options.num):
  108. # the same target cannot have the signature of all the tasks that update it
  109. # so the tasks will be executed each time
  110. bld(rule=try_compress, target=ini, always=True, kind=kind, frompath=node, files=rels)
  111. # for the same reason, count_result will be executed each time
  112. bld(rule=count_result, target=dist, source=[ini], always=True)
  113. bld(rule=write_template, target=plot, triplet=[png, kind, dist], always=True)
  114. bld(rule='${GNUPLOT} < ${SRC[1].abspath()}', target=png, source=[dist, plot])