change API and make various optimizations