در این سؤال شما باید با کمک پایتون یک سیستم توزیعشده با استفاده از چند ورکر *(worker)* برای انجام انواع *join* بر روی جداول پیادهسازی کنید.
# پروژهی اولیه
پروژهی اولیه را از [این لینک](/problemset/assignments/4367/download_problem_initial_project/254218/) دانلود کنید. ساختار فایلهای این پروژه بهصورت زیر است.
```
joiner.zip
└── joiner.py
```
# تعاریف
### نُد مستر
- مستر، دو جدول را که بهصورت آرایهی دوبعدی هستند (هر آرایه یک سطر از جدول را تشکیل میدهد و سطر اول نام ستونها را شامل میشود) به عنوان ورودی دریافت میکند و عمل جوین مورد نیاز را بر روی فیلد مشخصی انجام میدهد و این عمل را بین ورکرها توزیع میکند.
- ایندکس فیلدی که روی آن باید جوین صورت بگیرد، در تابع `find_on_index` مشخص میشود.
- مستر در تابع `split_data` جدول اول را به بخشهای مساوی تقسیم میکند؛ به این صورت که هر بخش به اندازهی نسبت سطرها به تعداد ورکرهاست و جوین هر بخش را به یک ورکر میسپارد.
- مستر باید بتواند جوابهای ورکرها را در `combine_results` جمعبندی کند و حاصل نهایی را بهصورت آرایهی دوبعدی به کاربر اعلام کند.
### نُد ورکر
- هر ورکر جوین مشخصشده را روی بخش مشخصشده از جدولها انجام میدهد و همچنین با توجه به ورودی on مشخص میکند که روی چه فیلدی باید جوین بزند. **تضمین میشود index و نام ستونی که باید روی آن جوین زد در هر دو جدول برابر است.**
### جوینها
%align_right_start%
سیستم باید بتواند چهار جوین اصلی را محاسبه کند:
1. `full`
2. `left`
3. `right`
4. `inner`
### ارتباط بین مستر و ورکر
مستر از طریق یک thread که تابع `perform_task` را صدا میزند با ورکر در ارتباط است و پس از اتمام کار ورکر این تابع مقداری را باز میگرداند.
# پیادهسازی
## توابع جوین
شما باید هر چهار تابع جوین را در کلاس ورکر پیادهسازی کنید.
## تابع `split_data`
شما باید در این تابع هدرهای هر دو جدول را حذف و جدول اول را به بخشهای تا حد امکان مساوی تقسیم کنید و در آرایهای از تاپلها که هر تاپل یک بخش از جدول اول و جدول دوم بدون هدر را در خود دارد، بازگردانید.
## تابع `find_on_index`
در این تابع شما باید عدد ایندکسی که رشتهی آن به شما داده شده را برگردانید تا بتوانید روی آن ایندکس جوین بزنید.
## تابع `combine_results`
تمام پاسخها را در یک آرایه جمع و بازمیگرداند.
## تابع `distribute_tasks`
با استفاده از توابع بالا جداول را تبدیل به یکسری بخش میکند و هر محاسبات هر بخش را در یک thread به یک ورکر میسپارد و سپس آنها را تجمیع و بازمیگرداند.
# ورودی
همانطور که گفته شد، ورودیها دو جدول هستند و همچنین نوع جوین نیز و فیلدی که روی آن باید جوین زد، در ورودی داده میشود.
```python
worker_count = 3
master = MasterNode(worker_count)
table1 = [["id", "name"], [1, 'A'], [2, 'B'], [3, 'C']]
table2 = [["id", "dept"], [1, 'HR'], [2, 'Engineering']]
on = 'id'
join_type = 'inner'
master.start(join_type, table1, table2, on)
```
# خروجی
یک جدول که بهصورت آرایهی دوبعدیست.
**دقت کنید که همواره دادهی جدول اول مقدمتر است.**
```
[
[[1, 'A'], [1, 'HR']],
[[2, 'B'], [2, 'Engineering']]
]
```
# آنچه باید آپلود کنید
شما باید یک فایل *ZIP* با ساختار زیر را آپلود کنید.
```
[your-solution-file-name].zip
└── joiner.py
```