pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


New idmapper cache prototype
Posted by Anonymous on Mon 30th Mar 2026 15:26
raw | new post

  1. /* New idmapper cache prototype */
  2.  
  3. #include <windows.h>
  4. #include <stdbool.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <sys/queue.h>
  10.  
  11. #define IDMAPCACHE_TTL_SECONDS 60
  12. #define IDMAPCACHE_MAXNAME_LEN 256
  13.  
  14. /*
  15.  * Public API
  16.  */
  17. typedef signed long idmapcache_idnumber;
  18.  
  19. typedef struct _idmap_namestr {
  20.     char buf[IDMAPCACHE_MAXNAME_LEN];
  21.     size_t len;
  22. } idmap_namestr;
  23.  
  24. typedef struct _idmapcache_entry {
  25.     idmap_namestr win32name;
  26.     idmapcache_idnumber localid;
  27.  
  28.     idmap_namestr nfsname;
  29.     idmapcache_idnumber nfsid;
  30.  
  31.     time_t last_updated;
  32. } idmapcache_entry;
  33.  
  34. typedef struct _idmapcache_context idmapcache_context;
  35.  
  36. idmapcache_context *idmapcache_context_create(void);
  37. void idmapcache_context_destroy(idmapcache_context *restrict ctx);
  38. bool idmapcache_add(idmapcache_context *restrict ctx,
  39.     const char *restrict win32name,
  40.     idmapcache_idnumber localid,
  41.     const char *restrict nfsname,
  42.     idmapcache_idnumber nfsid);
  43. idmapcache_entry *idmapcache_lookup_by_win32name(idmapcache_context *restrict ctx,
  44.     const char *restrict win32name);
  45. idmapcache_entry *idmapcache_lookup_by_localid(idmapcache_context *restrict ctx,
  46.     idmapcache_idnumber search_localid);
  47. idmapcache_entry *idmapcache_lookup_by_nfsname(idmapcache_context *restrict ctx,
  48.     const char *restrict nfsname);
  49. idmapcache_entry *idmapcache_lookup_by_nfsid(idmapcache_context *restrict ctx,
  50.     idmapcache_idnumber search_nfslid);
  51. void idmapcache_entry_refcount_inc(idmapcache_entry *restrict e);
  52. void idmapcache_entry_refcount_dec(idmapcache_entry *restrict e);
  53.  
  54. /*
  55.  * Private
  56.  */
  57. struct idmapcache_node {
  58.     struct _idmapcache_entry entry;
  59.  
  60.     LIST_ENTRY(idmapcache_node) list_node;
  61.     volatile LONG refcounter;
  62. };
  63.  
  64. LIST_HEAD(idmapcache_head, idmapcache_node);
  65.  
  66. typedef struct _idmapcache_context {
  67.     struct idmapcache_head head;
  68.     SRWLOCK lock;
  69. } idmapcache_context;
  70.  
  71. typedef bool (*idmapcache_cmp_fn)(const struct idmapcache_node *restrict entry, const void *restrict search_val);
  72.  
  73. void idmapcache_entry_refcount_inc(idmapcache_entry *restrict e)
  74. {
  75.     struct idmapcache_node *en = (struct idmapcache_node *)e;
  76.     (void)InterlockedIncrement(&en->refcounter);
  77. }
  78.  
  79. void idmapcache_entry_refcount_dec(idmapcache_entry *restrict e)
  80. {
  81.     struct idmapcache_node *en = (struct idmapcache_node *)e;
  82.     if (InterlockedDecrement(&en->refcounter) == 0) {
  83.         free(e);
  84.     }
  85. }
  86.  
  87. static
  88. bool cmp_by_win32name(const struct idmapcache_node *restrict entry, const void *restrict search_val)
  89. {
  90.     const idmap_namestr *search_str = (const idmap_namestr *)search_val;
  91.  
  92.     if (search_str->len != entry->entry.win32name.len) {
  93.         return false;
  94.     }
  95.     return memcmp(entry->entry.win32name.buf, search_str->buf, search_str->len) == 0;
  96. }
  97.  
  98. static
  99. bool cmp_by_nfsname(const struct idmapcache_node *restrict entry, const void *restrict search_val)
  100. {
  101.     const idmap_namestr *search_str = (const idmap_namestr *)search_val;
  102.  
  103.     if (search_str->len != entry->entry.nfsname.len) {
  104.         return false;
  105.     }
  106.     return memcmp(entry->entry.nfsname.buf, search_str->buf, search_str->len) == 0;
  107. }
  108.  
  109. static
  110. bool cmp_by_localid(const struct idmapcache_node *restrict entry, const void *restrict search_val)
  111. {
  112.     return entry->entry.localid == *(const idmapcache_idnumber *)search_val;
  113. }
  114.  
  115. static
  116. bool cmp_by_nfsid(const struct idmapcache_node *restrict entry, const void *restrict search_val)
  117. {
  118.     return entry->entry.nfsid == *(const idmapcache_idnumber *)search_val;
  119. }
  120.  
  121. static
  122. idmapcache_entry *idmapcache_lookup(idmapcache_context *restrict ctx,
  123.     idmapcache_cmp_fn cmp,
  124.     const void *restrict search_val)
  125. {
  126.     struct idmapcache_node *found_node = NULL;
  127.     time_t current_time;
  128.     struct idmapcache_node *node;
  129.  
  130.     AcquireSRWLockShared(&ctx->lock);
  131.  
  132.     current_time = time(NULL);
  133.  
  134.     LIST_FOREACH(node, &ctx->head, list_node) {
  135.         if ((current_time - node->entry.last_updated) > IDMAPCACHE_TTL_SECONDS)
  136.             continue;
  137.  
  138.         if (cmp(node, search_val)) {
  139.             found_node = node;
  140.             idmapcache_entry_refcount_inc(&found_node->entry);
  141.             break;
  142.         }
  143.     }
  144.  
  145.     ReleaseSRWLockShared(&ctx->lock);
  146.  
  147.     return &found_node->entry;
  148. }
  149.  
  150. static
  151. void cleanup_expired_entries(idmapcache_context *restrict ctx, time_t current_time)
  152. {
  153.     struct idmapcache_node *node;
  154.     struct idmapcache_node *tmpnode;
  155.  
  156.     for (node = LIST_FIRST(&ctx->head) ; node != NULL ; node = tmpnode) {
  157.         tmpnode = LIST_NEXT(node, list_node);
  158.  
  159.         if ((current_time - node->entry.last_updated) > IDMAPCACHE_TTL_SECONDS) {
  160.             LIST_REMOVE(node, list_node);
  161.             idmapcache_entry_refcount_dec(&node->entry);
  162.         }
  163.     }
  164. }
  165.  
  166. idmapcache_context *idmapcache_context_create(void)
  167. {
  168.     idmapcache_context *ctx = malloc(sizeof(struct _idmapcache_context));
  169.     if (ctx == NULL)
  170.         return NULL;
  171.  
  172.     (void)memset(ctx, 0, sizeof(*ctx));
  173.     InitializeSRWLock(&ctx->lock);
  174.     LIST_INIT(&ctx->head);
  175.  
  176.     return ctx;
  177. }
  178.  
  179. void idmapcache_context_destroy(idmapcache_context *restrict ctx)
  180. {
  181.     AcquireSRWLockExclusive(&ctx->lock);
  182.  
  183.     struct idmapcache_node *node = LIST_FIRST(&ctx->head);
  184.     struct idmapcache_node *tmp;
  185.  
  186.     while (node != NULL) {
  187.         tmp = LIST_NEXT(node, list_node);
  188.         LIST_REMOVE(node, list_node);
  189.         idmapcache_entry_refcount_dec(&node->entry);
  190.  
  191.         node = tmp;
  192.     }
  193.  
  194.     ReleaseSRWLockExclusive(&ctx->lock);
  195.     free(ctx);
  196. }
  197.  
  198. bool idmapcache_add(idmapcache_context *restrict ctx,
  199.     const char *restrict win32name,
  200.     idmapcache_idnumber localid,
  201.     const char *restrict nfsname,
  202.     idmapcache_idnumber nfsid)
  203. {
  204.     size_t win32name_len = strlen(win32name);
  205.     if (win32name_len >= IDMAPCACHE_MAXNAME_LEN)
  206.         return false;
  207.  
  208.     size_t nfsname_len = strlen(nfsname);
  209.     if (nfsname_len >= IDMAPCACHE_MAXNAME_LEN)
  210.         return false;
  211.  
  212.     struct idmapcache_node *new_entry = malloc(sizeof(struct idmapcache_node));
  213.     if (new_entry == NULL)
  214.         return false;
  215.  
  216.     (void)memset(new_entry, 0, sizeof(*new_entry)); /* only debug */
  217.     new_entry->refcounter = 1L;
  218.  
  219.     (void)memcpy(new_entry->entry.win32name.buf, win32name, win32name_len);
  220.     new_entry->entry.win32name.buf[win32name_len] = '\0';
  221.     new_entry->entry.win32name.len = win32name_len;
  222.  
  223.     (void)memcpy(new_entry->entry.nfsname.buf, nfsname, nfsname_len);
  224.     new_entry->entry.nfsname.buf[nfsname_len] = '\0';
  225.     new_entry->entry.nfsname.len = nfsname_len;
  226.  
  227.     new_entry->entry.localid = localid;
  228.     new_entry->entry.nfsid = nfsid;
  229.  
  230.     AcquireSRWLockExclusive(&ctx->lock);
  231.  
  232.     time_t current_time = time(NULL);
  233.     new_entry->entry.last_updated = current_time;
  234.  
  235.     cleanup_expired_entries(ctx, current_time);
  236.     LIST_INSERT_HEAD(&ctx->head, new_entry, list_node);
  237.  
  238.     ReleaseSRWLockExclusive(&ctx->lock);
  239.  
  240.     return true;
  241. }
  242.  
  243. idmapcache_entry *idmapcache_lookup_by_win32name(idmapcache_context *restrict ctx,
  244.     const char *restrict win32name)
  245. {
  246.     idmap_namestr search_term;
  247.     search_term.len = strlen(win32name);
  248.     if (search_term.len >= IDMAPCACHE_MAXNAME_LEN)
  249.         return NULL;
  250.     (void)memcpy(search_term.buf, win32name, search_term.len);
  251.  
  252.     return idmapcache_lookup(ctx, cmp_by_win32name, &search_term);
  253. }
  254.  
  255. idmapcache_entry *idmapcache_lookup_by_localid(idmapcache_context *restrict ctx,
  256.     idmapcache_idnumber search_localid)
  257. {
  258.     return idmapcache_lookup(ctx, cmp_by_localid, &search_localid);
  259. }
  260.  
  261. idmapcache_entry *idmapcache_lookup_by_nfsname(idmapcache_context *restrict ctx,
  262.     const char *restrict nfsname)
  263. {
  264.     idmap_namestr search_term;
  265.     search_term.len = strlen(nfsname);
  266.     if (search_term.len >= IDMAPCACHE_MAXNAME_LEN)
  267.         return NULL;
  268.     (void)memcpy(search_term.buf, nfsname, search_term.len);
  269.  
  270.     return idmapcache_lookup(ctx, cmp_by_nfsname, &search_term);
  271. }
  272.  
  273. idmapcache_entry *idmapcache_lookup_by_nfsid(idmapcache_context *restrict ctx,
  274.     idmapcache_idnumber search_nfsid)
  275. {
  276.     return idmapcache_lookup(ctx, cmp_by_nfsid, &search_nfsid);
  277. }
  278.  
  279. int main(int ac, char *av[])
  280. {
  281.     (void)ac;
  282.     (void)av;
  283.  
  284.     idmapcache_context *cache = idmapcache_context_create();
  285.     if (cache == NULL) {
  286.         (void)fprintf(stderr, "Failed to allocate cache context.\n");
  287.         return 1;
  288.     }
  289.  
  290.     (void)printf("# Populating cache...\n");
  291.  
  292.     (void)idmapcache_add(cache, "System2",  100, "Kernel2",     1000);
  293.     (void)idmapcache_add(cache, "User1",    200, "Explorer1",   2000);
  294.  
  295.     idmapcache_entry *result;
  296.  
  297.     (void)printf("\n# --- Running Lookups ---\n");
  298.  
  299.     result = idmapcache_lookup_by_win32name(cache, "System2");
  300.     if (result) {
  301.         (void)printf("[OK] Found by win32name ('System'): localid = %ld, nfsid = %ld\n", (long)result->localid, (long)result->nfsid);
  302.         idmapcache_entry_refcount_dec(result);
  303.     } else {
  304.         (void)printf("[FAIL] Could not find 'System'\n");
  305.     }
  306.  
  307.     result = idmapcache_lookup_by_nfsname(cache, "Explorer1");
  308.     if (result) {
  309.         (void)printf("[OK] Found by nfsname ('Explorer'): win32name = %s, localid = %ld\n", result->win32name.buf, (long)result->localid);
  310.         idmapcache_entry_refcount_dec(result);
  311.     } else {
  312.         (void)printf("[FAIL] Could not find 'Explorer'\n");
  313.     }
  314.  
  315.     idmapcache_idnumber search_localid = 200;
  316.     result = idmapcache_lookup_by_localid(cache, search_localid);
  317.     if (result) {
  318.         (void)printf("[OK] Found by localid (200): win32name = %s, nfsname = %s\n", result->win32name.buf, result->nfsname.buf);
  319.         idmapcache_entry_refcount_dec(result);
  320.     } else {
  321.         (void)printf("[FAIL] Could not find localid = 200\n");
  322.     }
  323.  
  324.     idmapcache_idnumber search_nfsid = 2000;
  325.     result = idmapcache_lookup_by_nfsid(cache, search_nfsid);
  326.     if (result) {
  327.         (void)printf("[OK] Found by nfsid (2000): win32name = %s, nfsname = %s\n", result->win32name.buf, result->nfsname.buf);
  328.         idmapcache_entry_refcount_dec(result);
  329.     } else {
  330.         (void)printf("[FAIL] Could not find nfsid = 2000\n");
  331.     }
  332.  
  333.     (void)printf("\n# Destroying cache...\n");
  334.     idmapcache_context_destroy(cache);
  335.     (void)printf("#### Done.\n");
  336.  
  337.     return 0;
  338. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at