«بافر حلقهای»، «بافر چرخهای» یا «بافر حلقوی» یک ساختار داده است که از یک بافر واحد با اندازهی ثابت استفاده میکند، طوریکه انگار دو سر آن به هم متصل شده است.
بافر حلقهای ابتدا خالی است و طولی از پیش تعیینشده دارد. برای مثال، این یک بافر ۷ عنصری است:
[ ][ ][ ][ ][ ][ ][ ]
فرض کنید عدد ۱ در میانهی بافر نوشته میشود (مکان دقیق شروع در بافر حلقهای اهمیتی ندارد):
[ ][ ][ ][1][ ][ ][ ]
سپس فرض کنید دو عنصر دیگر، ۲ و ۳، اضافه میشوند که بعد از ۱ قرار میگیرند:
[ ][ ][ ][1][2][3][ ]
اگر سپس دو عنصر از بافر حذف شوند، قدیمیترین مقدارهای داخل بافر حذف میشوند. دو عنصری که در این حالت حذف میشوند ۱ و ۲ هستند و بافر تنها با ۳ باقی میماند:
[ ][ ][ ][ ][ ][3][ ]
اگر بافر ۷ عنصر داشته باشد، کاملاً پر است:
[5][6][7][8][9][3][4]
وقتی بافر پر باشد، خطایی ایجاد میشود و به کاربر اطلاع میدهد که نوشتنهای بعدی تا آزاد شدن یک خانه مسدود است.
وقتی بافر پر است، کاربر میتواند با یک نوشتن اجباری، قدیمیترین داده را بازنویسی کند. در این حالت، دو عنصر دیگر، A و B، اضافه میشوند و ۳ و ۴ را بازنویسی میکنند:
[5][6][7][8][9][A][B]
۳ و ۴ با A و B جایگزین شدهاند و اکنون ۵ قدیمیترین دادهی بافر است. در پایان، اگر دو عنصر حذف شوند، آنچه برگردانده میشود ۵ و ۶ است و بافر زیر را به دست میدهد:
[ ][ ][7][8][9][A][B]
چون فضا موجود است، اگر کاربر دوباره از بازنویسی برای ذخیرهی C و D استفاده کند، فضایی که پیشتر ۵ و ۶ در آن ذخیره شده بودند استفاده میشود، نه محل ۷ و ۸. ۷ هنوز قدیمیترین عنصر است و بافر دوباره پر شده است.
[C][D][7][8][9][A][B]
گاهی لازم است در کد خود، استثناها را هم سفارشیسازی کنید و هم raise کنید. وقتی این کار را میکنید، همیشه باید یک پیام خطای معنادار بگنجانید تا مشخص شود منشأ خطا چیست. این کار کد شما را خواناتر میکند و بهشکل چشمگیری به اشکالزدایی کمک میکند.
استثناهای سفارشی را میتوان از طریق کلاسهای استثنای جدید ساخت (برای جزئیات بیشتر classes را ببینید) که معمولاً زیرکلاسهایی از Exception هستند.
در موقعیتهایی که میدانید منشأ خطا از نوع خاصی از استثنا مشتق میشود، میتوانید انتخاب کنید که از یکی از built in error types زیر کلاس Exception ارثبری کنید. هنگام ایجاد خطا هم باز باید یک پیام معنادار بگنجانید.
این تمرین خاص از شما میخواهد که دو استثنای سفارشی بسازید. یک استثنا برای وقتی که بافر حلقوی شما پر است و باید ایجاد («پرتاب») شود، و یکی برای وقتی که خالی است. تستها فقط در صورتی قبول میشوند که استثناهای مناسب را سفارشیسازی کنید، همان استثناها را raise کنید و پیامهای خطای مناسب را بگنجانید.
برای سفارشیسازی یک built-in exception، یک class بسازید که از آن استثنا ارثبری میکند. وقتی استثنای سفارشی را همراه با یک پیام ایجاد میکنید، پیام را بهصورت آرگومان به نوع exception بنویسید:
# subclassing the built-in BufferError to create BufferFullException
class BufferFullException(BufferError):
"""Exception raised when CircularBuffer is full.
message: explanation of the error.
"""
def __init__(self, message):
self.message = message
# raising a BufferFullException
raise BufferFullException("Circular buffer is full")
در Exercism ثبتنام کنید تا Python را همراه با 17 مفهوم146 تمرین و مربیگری انسانی واقعی یاد بگیرید و در آن استاد شوید، همهی اینها رایگان.
در این ویدیو نگاهی به بافر حلقهای میاندازیم: اینکه چیست، کجاها استفاده میشود و چه پیادهسازیهای مختلفی دارد، از جمله صفها، آرایههای ایستا و پویا، ساختارهای دادهی تغییرناپذیر و یک پیادهسازی سرگرمکنندهی مبتنی بر ایجنت.