Lua1.0 code analysis hash. c

Source: Internet
Author: User

Hash. C code analysis

The most important data structure and related operations in Lua.

Let's take a look at several external interfaces.

/*** Create a new hash. Return the hash pointer or NULL on error.*/Hash *lua_hashcreate (unsigned int nhash){ Hash *t = new (Hash); if (t == NULL) {  lua_error ("not enough memory");  return NULL; } nhash(t) = nhash; markarray(t) = 0; nodelist(t) = newvector (nhash, Node*); if (nodelist(t) == NULL) {  lua_error ("not enough memory");  return NULL; } return t;}

Create an associated array. The input parameter is the size of the associated array.
Create an associated array.
Set the size.
Mark.
Create a pointer array.

Void lua_hashdelete (hash * H );
Release the associated array.


/*** If the hash node is present, return its pointer, otherwise create a new** node for the given reference and also return its pointer.** On error, return NULL.*/Object *lua_hashdefine (Hash *t, Object *ref){ int h; Node *n; h = head (t, ref); if (h < 0) return NULL; n = present(t, ref, h); if (n == NULL) {  n = new(Node);  if (n == NULL)  {   lua_error ("not enough memory");   return NULL;  }  n->ref = *ref;  tag(&n->val) = T_NIL;  n->next = list(t,h); /* link node to head of list */  list(t,h) = n; } return (&n->val);}

Check whether the specified item exists in the associated array. If yes, return its pointer.
If it does not exist, a new node will also return its pointer.
Returns the header of the join reference in the joined array.
The header of the array associated with the data to check whether the reference exists in the associated array:
If the node does not exist, create a new node, set its reference to the input parameter, and set its value to null to insert the new node to the header.
If yes, return its value directly.

Let's take a look at the implementation of head and present:

static int head (Hash *t, Object *ref) /* hash function */{ if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t)); else if (tag(ref) == T_STRING) {  int h;  char *name = svalue(ref);  for (h=0; *name!=0; name++) /* interpret name as binary number */  {   h <<= 8;   h += (unsigned char) *name; /* avoid sign extension */   h %= nhash(t); /* make it a valid index */  }  return h; } else {  lua_reportbug ("unexpected type to index table");  return -1; }}

The Correlated array is divided into two parts: the numerical part and the reference part.
The subscript of the value is obtained through the remainder of the value size and the size of the associated array.
Currently, only the string type is supported.
The hash value of a string is obtained through an algorithm.
The specific algorithm is to remove the ASCII code of a string eight digits left and then add the sum and the size of the associated array to the remainder.

Let's look at the implementation of present.

static Node *present(Hash *t, Object *ref, int h){ Node *n=NULL, *p; if (tag(ref) == T_NUMBER) {  for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)   if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break; } else if (tag(ref) == T_STRING) {  for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next)   if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break; } if (n==NULL) /* name not present */  return NULL;#if 0 if (p!=NULL) /* name present but not first */ {  p->next=n->next; /* move-to-front self-organization */  n->next=list(t,h);  list(t,h)=n; }#endif return n;}

Find the corresponding linked list through the array and subscript, and find whether the specified value exists in the linked list. If yes, return node. If no, return null.

Void lua_hashmark (hash * H)
Mark all nodes in the associated array.

Let's look at the implementation of lua_next.

void lua_next (void){ Hash *a; Object *o = lua_getparam (1); Object *r = lua_getparam (2); if (o == NULL || r == NULL) { lua_error ("too few arguments to function `next‘"); return; } if (lua_getparam (3) != NULL) { lua_error ("too many arguments to function `next‘"); return; } if (tag(o) != T_ARRAY) { lua_error ("first argument of function `next‘ is not a table"); return; } a = avalue(o); if (tag(r) == T_NIL) {  firstnode (a, 0);  return; } else {  int h = head (a, r);  if (h >= 0)  {   Node *n = list(a,h);   while (n)   {    if (memcmp(&n->ref,r,sizeof(Object)) == 0)    {     if (n->next == NULL)     {      firstnode (a, h+1);      return;     }     else if (tag(&n->next->val) != T_NIL)     {      lua_pushobject (&n->next->ref);      lua_pushobject (&n->next->val);      return;     }     else     {      Node *next = n->next->next;      while (next != NULL && tag(&next->val) == T_NIL) next = next->next;      if (next == NULL)      {       firstnode (a, h+1);       return;      }      else      {       lua_pushobject (&next->ref);       lua_pushobject (&next->val);      }      return;     }    }    n = n->next;   }   if (n == NULL)    lua_error ("error in function ‘next‘: reference not found");  } }}

It is called when next is called in the Lua script. The function is to traverse arrays.
Given an array and a reference, return the next node of the given reference in the array.
If a null value is given, the first node of the array is returned.
Otherwise, the next non-empty node of the value in the array is returned.
Two values are returned to the Lua script.
Let's take a look at the built-in test program (array. Lua) that uses it ):

a = @()i=0while i<10 do a[i] = i*i i=i+1endr,v = next(a,nil)while r ~= nil do print ("array["..r.."] = "..v) r,v = next(a,r)end

This program will print the following:
Array [0] = 0
Array [1] = 1
Array [2] = 4
Array [3] = 9
Array [4] = 16
Array [5] = 25
Array [6] = 36
Array [7] = 49
Array [8] = 64
Array [9] = 81

Lua1.0 code analysis hash. c

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.