hsearch(3)

الاسم
hcreate, hdestroy, hsearch, hcreate_r, hdestroy_r, hsearch_r - إدارة جدول التجزئة

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <search.h>

int hcreate(size_t nel);
void hdestroy(void);

ENTRY *hsearch(ENTRY item, ACTION action);

#define _GNU_SOURCE         /* انظر feature_test_macros(7) */
#include <search.h>

int hcreate_r(size_t nel, struct hsearch_data *htab);
void hdestroy_r(struct hsearch_data *htab);

int hsearch_r(ENTRY item, ACTION action, ENTRY **retval,
              struct hsearch_data *htab);

الوصف
الدوال الثلاث hcreate() و hsearch() و hdestroy() تسمح للمستدعي بإنشاء وإدارة جدول بحث تجزئة يحتوي على مدخلات تتكون من مفتاح (سلسلة محارف) وبيانات مرتبطة. باستخدام هذه الدوال، يمكن استخدام جدول تجزئة واحد فقط في كل مرة.

الدوال الثلاث hcreate_r() و hsearch_r() و hdestroy_r() هي إصدارات قابلة لإعادة الدخول تسمح للبرنامج باستخدام أكثر من جدول بحث تجزئة في نفس الوقت. المعامل الأخير htab يشير إلى بنية تصف الجدول الذي ستعمل عليه الدالة. يجب على المبرمج معاملة هذه البنية كبنية معتمة (أي لا يحاول الوصول المباشر أو تعديل الحقول في هذه البنية).

أولاً، يجب إنشاء جدول تجزئة باستخدام hcreate(). المعامل nel يحدد الحد الأقصى لعدد المدخلات في الجدول. (لا يمكن تغيير هذا الحد الأقصى لاحقًا، لذا اختره بحكمة.) قد يعدل التطبيق هذه القيمة لأعلى لتحسين أداء جدول التجزئة الناتج.

الدالة hcreate_r() تؤدي نفس مهمة hcreate()، ولكن للجدول الموصوف بواسطة البنية *htab. يجب تصفير البنية المشار إليها بواسطة htab قبل الاستدعاء الأول لـ hcreate_r().

الدالة hdestroy() تحرر الذاكرة التي يشغلها جدول التجزئة الذي أُنشئ بواسطة hcreate(). بعد استدعاء hdestroy()، يمكن إنشاء جدول تجزئة جديد باستخدام hcreate(). الدالة hdestroy_r() تؤدي المهمة المماثلة لجدول تجزئة موصوف بواسطة *htab، والذي أُنشئ سابقًا باستخدام hcreate_r().

الدالة hsearch() تبحث في جدول التجزئة عن عنصر بنفس مفتاح item (حيث يُحدد "نفس" باستخدام strcmp(3))، وإذا نجحت، تُرجع مؤشرًا إليه.

المعامل item من النوع ENTRY، والذي يُعرف في <search.h> كالتالي:

    typedef struct entry {
        char *key;
        void *data;
    } ENTRY;

الحقل key يشير إلى سلسلة محارف منتهية بقيمة خالية وهي مفتاح البحث. الحقل data يشير إلى بيانات مرتبطة بذلك المفتاح.

المعامل action يحدد ما تفعله hsearch() بعد بحث غير ناجح. يجب أن يكون لهذا المعامل إما القيمة ENTER، بمعنى إدراج نسخة من item (وإرجاع مؤشر إلى مدخل جدول التجزئة الجديد كنتيجة للدالة)، أو القيمة FIND، بمعنى أنه يجب إرجاع NULL. (إذا كان action هو FIND، فسيتم تجاهل data.)

الدالة hsearch_r() تشبه hsearch() ولكنها تعمل على جدول التجزئة الموصوف بواسطة *htab. تختلف الدالة hsearch_r() عن hsearch() في أن مؤشرًا إلى العنصر الموجود يُرجع في *retval، بدلاً من كونه نتيجة الدالة.

قيمة الإرجاع
hcreate() و hcreate_r() تُرجعان قيمة غير صفرية عند النجاح. تُرجعان 0 عند الخطأ، مع تعيين errno للإشارة إلى الخطأ.

عند النجاح، hsearch() تُرجع مؤشرًا إلى مدخل في جدول التجزئة. hsearch() تُرجع NULL عند الخطأ، أي إذا كان action هو ENTER وجدول التجزئة ممتلئ، أو action هو FIND ولا يمكن العثور على item في جدول التجزئة. hsearch_r() تُرجع قيمة غير صفرية عند النجاح، و0 عند الخطأ. في حالة حدوث خطأ، تعيّن هاتان الدالتان errno للإشارة إلى الخطأ.

الأخطاء
يمكن أن تفشل hcreate_r() و hdestroy_r() للأسباب التالية:

EINVAL
    htab هو NULL.

قد تفشل hsearch() و hsearch_r() للأسباب التالية:

ENOMEM
    كان action هو ENTER، ولم يُعثر على key في الجدول، ولم تكن هناك مساحة في الجدول لإضافة مدخل جديد.

ESRCH
    كان action هو FIND، ولم يُعثر على key في الجدول.

يحدد POSIX.1 خطأ ENOMEM فقط.

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
hcreate(), hsearch(), hdestroy() | سلامة الخيوط | MT-Unsafe race:hsearch
hcreate_r(), hsearch_r(), hdestroy_r() | سلامة الخيوط | MT-Safe race:htab

المعايير

hcreate()
hsearch()
hdestroy()
    POSIX.1-2008.

hcreate_r()
hsearch_r()
hdestroy_r()
    GNU.

التاريخ

hcreate()
hsearch()
hdestroy()
    SVr4, POSIX.1-2001.

hcreate_r()
hsearch_r()
hdestroy_r()
    GNU.

ملاحظات
تكون تطبيقات جداول التجزئة عادةً أكثر كفاءة عندما يحتوي الجدول على مساحة خالية كافية لتقليل التصادمات. عادةً، يعني هذا أن nel يجب أن يكون أكبر بنسبة 25% على الأقل من الحد الأقصى لعدد العناصر التي يتوقع المتصل تخزينها في الجدول.

لا تحرر الدالتان hdestroy() و hdestroy_r() المخازن المؤقتة المشار إليها بواسطة عنصري key و data في مدخلات جدول التجزئة. (لا تستطيع فعل ذلك لأنها لا تعرف ما إذا كانت هذه المخازن المؤقتة قد خُصصت ديناميكيًا.) إذا احتاجت هذه المخازن المؤقتة إلى التحرير (ربما لأن البرنامج ينشئ ويدمر جداول التجزئة بشكل متكرر، بدلاً من إنشاء جدول واحد يتطابق عمره مع عمر البرنامج)، فيجب على البرنامج الحفاظ على هياكل بيانات محاسبية تسمح له بتحريرها.

العلل
تحدد SVr4 و POSIX.1-2001 أن action مهم فقط للبحث غير الناجح، بحيث لا ينبغي لـ ENTER فعل أي شيء للبحث الناجح. في libc و glibc (قبل glibc 2.3)، يخالف التطبيق المواصفات، حيث يُحدّث data للمفتاح key المُعطى في هذه الحالة.

يمكن إضافة مدخلات جدول التجزئة الفردية، ولكن لا يمكن حذفها.

أمثلة
يُدرج البرنامج التالي 24 عنصرًا في جدول تجزئة، ثم يطبع بعضًا منها.

    #include <search.h>
    #include <stdio.h>
    #include <stdlib.h>

    static char *data[] = { "alpha", "bravo", "charlie", "delta",
         "echo", "foxtrot", "golf", "hotel", "india", "juliet",
         "kilo", "lima", "mike", "november", "oscar", "papa",
         "quebec", "romeo", "sierra", "tango", "uniform",
         "victor", "whisky", "x-ray", "yankee", "zulu"
    };

    int
    main(void)
    {
        ENTRY e;
        ENTRY *ep;

        hcreate(30);

        for (size_t i = 0; i < 24; i++) {
            e.key = data[i];
            /* data is just an integer, instead of a
               pointer to something */
            e.data = (void *) i;
            ep = hsearch(e, ENTER);
            /* there should be no failures */
            if (ep == NULL) {
                fprintf(stderr, "entry failed\n");
                exit(EXIT_FAILURE);
            }
        }

        for (size_t i = 22; i < 26; i++) {
            /* print two entries from the table, and
               show that two are not in the table */
            e.key = data[i];
            ep = hsearch(e, FIND);
            printf("%9.9s -> %9.9s:%d\n", e.key,
                   ep ? ep->key : "NULL", ep ? (int) ep->data : 0);
        }
        hdestroy();
        exit(EXIT_SUCCESS);
    }

انظر أيضًا
bsearch(3)، lsearch(3)، malloc(3)، tsearch(3)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.