finished single thread version