Guest User

Untitled

a guest
Jun 29th, 2018
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.03 KB | None | 0 0
  1. import random
  2. import threading
  3.  
  4.  
  5. FILE = '/tmp/foobarbaz.tmp'
  6.  
  7. LIST = []
  8. LOCK = threading.Lock()
  9. LINES_READ = 0
  10. READER_FINISHED = False
  11. FILTERED_UNTIL = 0
  12. FILTER_FINISHED = False
  13. SORTED_UNTIL = 1
  14.  
  15.  
  16. def initialize_file(path):
  17.     lines = 1_000_000
  18.     values = lines / 100
  19.  
  20.     try:
  21.         with open(path, 'xt', encoding='ascii') as file:
  22.             lines = ('{:05X}\n'.format(random.randrange(0, values)) for _ in range(lines))
  23.             file.write(''.join(lines))
  24.         return True
  25.     except FileExistsError:
  26.         return False
  27.  
  28.  
  29. def reader_main():
  30.     global LINES_READ, READER_FINISHED
  31.     initialize_file(FILE)
  32.  
  33.     with open(FILE, 'rt', encoding='ascii') as file:
  34.         while True:
  35.             line = file.readline()
  36.             if not line:
  37.                 break
  38.             LIST.append(line)
  39.             LINES_READ += 1
  40.  
  41.     LOCK.acquire()
  42.     READER_FINISHED = True
  43.     LOCK.release()
  44.  
  45.  
  46. def filter_main():
  47.     global FILTERED_UNTIL, FILTER_FINISHED
  48.    
  49.     while True:
  50.         try:
  51.             LOCK.acquire()
  52.  
  53.             item = LIST[FILTERED_UNTIL]
  54.  
  55.             if item == '00000\n':
  56.                 LIST.pop(FILTERED_UNTIL)
  57.             else:
  58.                 FILTERED_UNTIL += 1
  59.  
  60.         except IndexError:
  61.             if READER_FINISHED:
  62.                 FILTER_FINISHED = True
  63.                 break
  64.         finally:
  65.             LOCK.release()
  66.  
  67.  
  68. def sorter_main():
  69.     global SORTED_UNTIL
  70.    
  71.     while True:
  72.         if SORTED_UNTIL >= FILTERED_UNTIL and not FILTER_FINISHED:
  73.             continue
  74.  
  75.         try:
  76.             item = LIST[SORTED_UNTIL]
  77.         except IndexError:
  78.             break
  79.  
  80.         begin, end = 0, SORTED_UNTIL
  81.         middle = (begin + end) // 2
  82.  
  83.         while True:
  84.             item_in_middle = LIST[middle]
  85.             insert_before = item < item_in_middle
  86.             if begin == middle:
  87.                 break
  88.             elif insert_before:
  89.                 end = middle
  90.             else:
  91.                 begin = middle
  92.             middle = (begin + end) // 2
  93.  
  94.         LOCK.acquire()
  95.         LIST.pop(SORTED_UNTIL)
  96.         LIST.insert(middle if insert_before else middle + 1, item)
  97.         LOCK.release()
  98.        
  99.         SORTED_UNTIL += 1
  100.  
  101.  
  102. def monitor_main():
  103.     import time
  104.     while True:
  105.         print(LINES_READ, FILTERED_UNTIL, SORTED_UNTIL)
  106.         time.sleep(5)
  107.  
  108.  
  109. def main():
  110.     reader = threading.Thread(target=reader_main)
  111.     reader.start()
  112.  
  113.     filter_ = threading.Thread(target=filter_main)
  114.     filter_.start()
  115.  
  116.     sorter = threading.Thread(target=sorter_main)
  117.     sorter.start()
  118.  
  119.     monitor = threading.Thread(target=monitor_main, daemon=True)
  120.     monitor.start()
  121.  
  122.     reader.join()
  123.     filter_.join()
  124.     sorter.join()
  125.  
  126.     print(''.join(LIST), end='')
  127.  
  128.     with open(FILE, 'rt', encoding='ascii') as file:
  129.         lines = file.readlines()
  130.     lines = list(sorted(l for l in lines if l != '00000\n'))
  131.  
  132.     print(LIST == lines)
  133.  
  134.     return LIST != lines
  135.  
  136.  
  137. if __name__ == '__main__':
  138.     exit(main())
Advertisement
Add Comment
Please, Sign In to add comment