Esempio n. 1
0
void
AddXkey(const CStr *Xkey, XmapVal *val, int ntype)
{
    CStr cs;
    cs.buf = Xkey->buf;
    cs.len = Xkey->len;
    if (Xkey->len == 0) {
	xprintf("%s", CGETS(9, 1, "AddXkey: Null extended-key not allowed.\n"));
	return;
    }

    if (ntype == XK_CMD && val->cmd == F_XKEY) {
	xprintf("%s",
	    CGETS(9, 2, "AddXkey: sequence-lead-in command not allowed\n"));
	return;
    }

    if (Xmap == NULL)
	/* tree is initially empty.  Set up new node to match Xkey[0] */
	Xmap = GetFreeNode(&cs);	/* it is properly initialized */

    /* Now recurse through Xmap */
    (void) TryNode(Xmap, &cs, val, ntype);	
    return;
}
/*
Performs a Boundary Package-Merge step. Puts a new chain in the given list. The
new chain is, depending on the weights, a leaf or a combination of two chains
from the previous list.
lists: The lists of chains.
maxbits: Number of lists.
leaves: The leaves, one per symbol.
numsymbols: Number of leaves.
pool: the node memory pool.
index: The index of the list in which a new chain or leaf is required.
*/
static void BoundaryPM(Node* (*lists)[2], int maxbits,
    Node* leaves, int numsymbols, NodePool* pool, int index) {
  int lastcount = lists[index][1]->count;  /* Count of last chain of list. */

  if (unlikely(!index && lastcount >= numsymbols)) return;

  Node* newchain = GetFreeNode(lists, maxbits, pool);
  Node* oldchain = lists[index][1];

  /* These are set up before the recursive calls below, so that there is a list
  pointing to the new node, to let the garbage collection know it's in use. */
  lists[index][0] = oldchain;
  lists[index][1] = newchain;

  if (unlikely(!index)) {
    /* New leaf node in list 0. */
    InitNode(leaves[lastcount].weight, lastcount + 1, 0, newchain);
  } else {
    size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;
    if (lastcount < numsymbols && sum > leaves[lastcount].weight) {
      /* New leaf inserted in list, so count is incremented. */
      InitNode(leaves[lastcount].weight, lastcount + 1, oldchain->tail, newchain);
    } else {
      InitNode(sum, lastcount, lists[index - 1][1], newchain);
      /* Two lookahead chains of previous list used up, create new ones. */
      BoundaryPM(lists, maxbits, leaves, numsymbols, pool, index - 1);
      BoundaryPM(lists, maxbits, leaves, numsymbols, pool, index - 1);
    }
  }
}
static void BoundaryPMfinal(Node* (*lists)[2], int maxbits,
                       Node* leaves, int numsymbols, NodePool* pool, int index) {
  int lastcount = lists[index][1]->count;  /* Count of last chain of list. */

  Node* newchain = GetFreeNode(lists, maxbits, pool);
  Node* oldchain = lists[index][1];

  /* These are set up before the recursive calls below, so that there is a list
   pointing to the new node, to let the garbage collection know it's in use. */
  lists[index][0] = oldchain;
  lists[index][1] = newchain;

  size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;
  if (lastcount < numsymbols && sum > leaves[lastcount].weight) {
    /* New leaf inserted in list, so count is incremented. */
    InitNode(leaves[lastcount].weight, lastcount + 1, oldchain->tail, newchain);
  } else {
    InitNode(sum, lastcount, lists[index - 1][1], newchain);
  }
}
Esempio n. 4
0
/*將資料插入串列中*/
int InsertAfter(ListNode table[], char OldData[], char NewData[]) {
    /*在資料為OldData的節點之後,加入新節點,資料為NewData[]*/
    int EmptyNode, i;
    EmptyNode = GetFreeNode(table); /*找空節點*/

    if (EmptyNode == 0) {           /*已經沒有空節點*/
        return FALSE;    /*告訴呼叫者此動作失敗*/
    }

    strcpy(table[EmptyNode].data, NewData);     /*複製資料到新節點*/
    i = SearchNode(table, OldData);     /*找出舊節點的位置*/

    if (i == FALSE) {
        return FALSE;
    }

    table[EmptyNode].next = table[i].next;  /*舊節點的次一元素變成新節點的次一元素*/
    table[i].next = EmptyNode;          /*改變舊節點的次一元素位置*/
    return TRUE;                        /*成功*/
}
Esempio n. 5
0
static int
TryNode(XmapNode *ptr, CStr *str, XmapVal *val, int ntype)
{
    /*
     * Find a node that matches *string or allocate a new one
     */
    if (ptr->ch != *(str->buf)) {
	XmapNode *xm;

	for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
	    if (xm->sibling->ch == *(str->buf))
		break;
	if (xm->sibling == NULL)
	    xm->sibling = GetFreeNode(str);	/* setup new node */
	ptr = xm->sibling;
    }

    str->buf++;
    str->len--;
    if (str->len == 0) {
	size_t len;

	/* we're there */
	if (ptr->next != NULL) {
	    PutFreeNode(ptr->next);	/* lose longer Xkeys with this prefix */
	    ptr->next = NULL;
	}

	switch (ptr->type) {
	case XK_STR:
	case XK_EXE:
	    xfree(ptr->val.str.buf);
	    ptr->val.str.len = 0;
	    break;
	case XK_NOD:
	case XK_CMD:
	    break;
	default:
	    abort();
	    break;
	}

	switch (ptr->type = ntype) {
	case XK_CMD:
	    ptr->val = *val;
	    break;
	case XK_STR:
	case XK_EXE:
	    ptr->val.str.len = val->str.len;
	    len = (val->str.len + 1) * sizeof(*ptr->val.str.buf);
	    ptr->val.str.buf = xmalloc(len);
	    (void) memcpy(ptr->val.str.buf, val->str.buf, len);
	    break;
	default:
	    abort();
	    break;
	}
    }
    else {
	/* still more chars to go */
	if (ptr->next == NULL)
	    ptr->next = GetFreeNode(str);	/* setup new node */
	(void) TryNode(ptr->next, str, val, ntype);
    }
    return (0);
}