Deleted Added
full compact
dict.c (77443) dict.c (94290)
1/*******************************************************************
2** d i c t . c
3** Forth Inspired Command Language - dictionary methods
4** Author: John Sadler (john_sadler@alum.mit.edu)
5** Created: 19 July 1997
1/*******************************************************************
2** d i c t . c
3** Forth Inspired Command Language - dictionary methods
4** Author: John Sadler (john_sadler@alum.mit.edu)
5** Created: 19 July 1997
6** $Id: dict.c,v 1.6 2000-06-17 07:43:44-07 jsadler Exp jsadler $
6** $Id: dict.c,v 1.14 2001/12/05 07:21:34 jsadler Exp $
7*******************************************************************/
8/*
9** This file implements the dictionary -- FICL's model of
10** memory management. All FICL words are stored in the
11** dictionary. A word is a named chunk of data with its
12** associated code. FICL treats all words the same, even
13** precompiled ones, so your words become first-class
14** extensions of the language. You can even define new
15** control structures.
16**
17** 29 jun 1998 (sadler) added variable sized hash table support
18*/
19/*
20** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
21** All rights reserved.
22**
23** Get the latest Ficl release at http://ficl.sourceforge.net
24**
7*******************************************************************/
8/*
9** This file implements the dictionary -- FICL's model of
10** memory management. All FICL words are stored in the
11** dictionary. A word is a named chunk of data with its
12** associated code. FICL treats all words the same, even
13** precompiled ones, so your words become first-class
14** extensions of the language. You can even define new
15** control structures.
16**
17** 29 jun 1998 (sadler) added variable sized hash table support
18*/
19/*
20** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
21** All rights reserved.
22**
23** Get the latest Ficl release at http://ficl.sourceforge.net
24**
25** I am interested in hearing from anyone who uses ficl. If you have
26** a problem, a success story, a defect, an enhancement request, or
27** if you would like to contribute to the ficl release, please
28** contact me by email at the address above.
29**
25** L I C E N S E and D I S C L A I M E R
26**
27** Redistribution and use in source and binary forms, with or without
28** modification, are permitted provided that the following conditions
29** are met:
30** 1. Redistributions of source code must retain the above copyright
31** notice, this list of conditions and the following disclaimer.
32** 2. Redistributions in binary form must reproduce the above copyright

--- 6 unchanged lines hidden (view full) ---

39** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
40** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46** SUCH DAMAGE.
30** L I C E N S E and D I S C L A I M E R
31**
32** Redistribution and use in source and binary forms, with or without
33** modification, are permitted provided that the following conditions
34** are met:
35** 1. Redistributions of source code must retain the above copyright
36** notice, this list of conditions and the following disclaimer.
37** 2. Redistributions in binary form must reproduce the above copyright

--- 6 unchanged lines hidden (view full) ---

44** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51** SUCH DAMAGE.
47**
48** I am interested in hearing from anyone who uses ficl. If you have
49** a problem, a success story, a defect, an enhancement request, or
50** if you would like to contribute to the ficl release, please send
51** contact me by email at the address above.
52**
53** $Id: dict.c,v 1.8 2001-04-26 21:41:45-07 jsadler Exp jsadler $
54*/
55
52*/
53
56/* $FreeBSD: head/sys/boot/ficl/dict.c 77443 2001-05-29 23:44:12Z dcs $ */
54/* $FreeBSD: head/sys/boot/ficl/dict.c 94290 2002-04-09 17:45:28Z dcs $ */
57
58#ifdef TESTMAIN
59#include <stdio.h>
55
56#ifdef TESTMAIN
57#include <stdio.h>
60#include <stdlib.h>
61#include <ctype.h>
62#else
63#include <stand.h>
64#endif
65#include <string.h>
66#include "ficl.h"
67
68/* Dictionary on-demand resizing control variables */

--- 230 unchanged lines hidden (view full) ---

299{
300 return pDict->here - pDict->dict;
301}
302
303
304/**************************************************************************
305 d i c t C h e c k
306** Checks the dictionary for corruption and throws appropriate
58#include <ctype.h>
59#else
60#include <stand.h>
61#endif
62#include <string.h>
63#include "ficl.h"
64
65/* Dictionary on-demand resizing control variables */

--- 230 unchanged lines hidden (view full) ---

296{
297 return pDict->here - pDict->dict;
298}
299
300
301/**************************************************************************
302 d i c t C h e c k
303** Checks the dictionary for corruption and throws appropriate
307** errors
304** errors.
305** Input: +n number of ADDRESS UNITS (not Cells) proposed to allot
306** -n number of ADDRESS UNITS proposed to de-allot
307** 0 just do a consistency check
308**************************************************************************/
308**************************************************************************/
309void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int nCells)
309void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int n)
310{
310{
311 if ((nCells >= 0) && (dictCellsAvail(pDict) < nCells))
311 if ((n >= 0) && (dictCellsAvail(pDict) * (int)sizeof(CELL) < n))
312 {
313 vmThrowErr(pVM, "Error: dictionary full");
314 }
315
312 {
313 vmThrowErr(pVM, "Error: dictionary full");
314 }
315
316 if ((nCells <= 0) && (dictCellsUsed(pDict) < -nCells))
316 if ((n <= 0) && (dictCellsUsed(pDict) * (int)sizeof(CELL) < -n))
317 {
318 vmThrowErr(pVM, "Error: dictionary underflow");
319 }
320
321 if (pDict->nLists > FICL_DEFAULT_VOCS)
322 {
323 dictResetSearchOrder(pDict);
324 vmThrowErr(pVM, "Error: search order overflow");

--- 66 unchanged lines hidden (view full) ---

391 nAlloc = sizeof (FICL_HASH) + nCells * sizeof (CELL)
392 + (nHash - 1) * sizeof (FICL_WORD *);
393
394 pDict = ficlMalloc(sizeof (FICL_DICT));
395 assert(pDict);
396 memset(pDict, 0, sizeof (FICL_DICT));
397 pDict->dict = ficlMalloc(nAlloc);
398 assert(pDict->dict);
317 {
318 vmThrowErr(pVM, "Error: dictionary underflow");
319 }
320
321 if (pDict->nLists > FICL_DEFAULT_VOCS)
322 {
323 dictResetSearchOrder(pDict);
324 vmThrowErr(pVM, "Error: search order overflow");

--- 66 unchanged lines hidden (view full) ---

391 nAlloc = sizeof (FICL_HASH) + nCells * sizeof (CELL)
392 + (nHash - 1) * sizeof (FICL_WORD *);
393
394 pDict = ficlMalloc(sizeof (FICL_DICT));
395 assert(pDict);
396 memset(pDict, 0, sizeof (FICL_DICT));
397 pDict->dict = ficlMalloc(nAlloc);
398 assert(pDict->dict);
399
399 pDict->size = nCells;
400 dictEmpty(pDict, nHash);
401 return pDict;
402}
403
404
405/**************************************************************************
406 d i c t C r e a t e W o r d l i s t

--- 48 unchanged lines hidden (view full) ---

455 pDict->pForthWords = pHash;
456 pDict->smudge = NULL;
457 dictResetSearchOrder(pDict);
458 return;
459}
460
461
462/**************************************************************************
400 pDict->size = nCells;
401 dictEmpty(pDict, nHash);
402 return pDict;
403}
404
405
406/**************************************************************************
407 d i c t C r e a t e W o r d l i s t

--- 48 unchanged lines hidden (view full) ---

456 pDict->pForthWords = pHash;
457 pDict->smudge = NULL;
458 dictResetSearchOrder(pDict);
459 return;
460}
461
462
463/**************************************************************************
464 d i c t H a s h S u m m a r y
465** Calculate a figure of merit for the dictionary hash table based
466** on the average search depth for all the words in the dictionary,
467** assuming uniform distribution of target keys. The figure of merit
468** is the ratio of the total search depth for all keys in the table
469** versus a theoretical optimum that would be achieved if the keys
470** were distributed into the table as evenly as possible.
471** The figure would be worse if the hash table used an open
472** addressing scheme (i.e. collisions resolved by searching the
473** table for an empty slot) for a given size table.
474**************************************************************************/
475#if FICL_WANT_FLOAT
476void dictHashSummary(FICL_VM *pVM)
477{
478 FICL_DICT *dp = vmGetDict(pVM);
479 FICL_HASH *pFHash;
480 FICL_WORD **pHash;
481 unsigned size;
482 FICL_WORD *pFW;
483 unsigned i;
484 int nMax = 0;
485 int nWords = 0;
486 int nFilled;
487 double avg = 0.0;
488 double best;
489 int nAvg, nRem, nDepth;
490
491 dictCheck(dp, pVM, 0);
492
493 pFHash = dp->pSearch[dp->nLists - 1];
494 pHash = pFHash->table;
495 size = pFHash->size;
496 nFilled = size;
497
498 for (i = 0; i < size; i++)
499 {
500 int n = 0;
501 pFW = pHash[i];
502
503 while (pFW)
504 {
505 ++n;
506 ++nWords;
507 pFW = pFW->link;
508 }
509
510 avg += (double)(n * (n+1)) / 2.0;
511
512 if (n > nMax)
513 nMax = n;
514 if (n == 0)
515 --nFilled;
516 }
517
518 /* Calc actual avg search depth for this hash */
519 avg = avg / nWords;
520
521 /* Calc best possible performance with this size hash */
522 nAvg = nWords / size;
523 nRem = nWords % size;
524 nDepth = size * (nAvg * (nAvg+1))/2 + (nAvg+1)*nRem;
525 best = (double)nDepth/nWords;
526
527 sprintf(pVM->pad,
528 "%d bins, %2.0f%% filled, Depth: Max=%d, Avg=%2.1f, Best=%2.1f, Score: %2.0f%%",
529 size,
530 (double)nFilled * 100.0 / size, nMax,
531 avg,
532 best,
533 100.0 * best / avg);
534
535 ficlTextOut(pVM, pVM->pad, 1);
536
537 return;
538}
539#endif
540
541/**************************************************************************
463 d i c t I n c l u d e s
464** Returns TRUE iff the given pointer is within the address range of
465** the dictionary.
466**************************************************************************/
467int dictIncludes(FICL_DICT *pDict, void *p)
468{
469 return ((p >= (void *) &pDict->dict)
470 && (p < (void *)(&pDict->dict + pDict->size))
471 );
472}
473
542 d i c t I n c l u d e s
543** Returns TRUE iff the given pointer is within the address range of
544** the dictionary.
545**************************************************************************/
546int dictIncludes(FICL_DICT *pDict, void *p)
547{
548 return ((p >= (void *) &pDict->dict)
549 && (p < (void *)(&pDict->dict + pDict->size))
550 );
551}
552
474
475/**************************************************************************
476 d i c t L o o k u p
477** Find the FICL_WORD that matches the given name and length.
478** If found, returns the word's address. Otherwise returns NULL.
479** Uses the search order list to search multiple wordlists.
480**************************************************************************/
481FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si)
482{

--- 13 unchanged lines hidden (view full) ---

496 }
497
498 ficlLockDictionary(0);
499 return pFW;
500}
501
502
503/**************************************************************************
553/**************************************************************************
554 d i c t L o o k u p
555** Find the FICL_WORD that matches the given name and length.
556** If found, returns the word's address. Otherwise returns NULL.
557** Uses the search order list to search multiple wordlists.
558**************************************************************************/
559FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si)
560{

--- 13 unchanged lines hidden (view full) ---

574 }
575
576 ficlLockDictionary(0);
577 return pFW;
578}
579
580
581/**************************************************************************
504 d i c t L o o k u p L o c
582 f i c l L o o k u p L o c
505** Same as dictLookup, but looks in system locals dictionary first...
506** Assumes locals dictionary has only one wordlist...
507**************************************************************************/
508#if FICL_WANT_LOCALS
583** Same as dictLookup, but looks in system locals dictionary first...
584** Assumes locals dictionary has only one wordlist...
585**************************************************************************/
586#if FICL_WANT_LOCALS
509FICL_WORD *dictLookupLoc(FICL_DICT *pDict, STRINGINFO si)
587FICL_WORD *ficlLookupLoc(FICL_SYSTEM *pSys, STRINGINFO si)
510{
511 FICL_WORD *pFW = NULL;
588{
589 FICL_WORD *pFW = NULL;
512 FICL_HASH *pHash = ficlGetLoc()->pForthWords;
590 FICL_DICT *pDict = pSys->dp;
591 FICL_HASH *pHash = ficlGetLoc(pSys)->pForthWords;
513 int i;
514 UNS16 hashCode = hashHashCode(si);
515
516 assert(pHash);
517 assert(pDict);
518
519 ficlLockDictionary(1);
520 /*

--- 265 unchanged lines hidden ---
592 int i;
593 UNS16 hashCode = hashHashCode(si);
594
595 assert(pHash);
596 assert(pDict);
597
598 ficlLockDictionary(1);
599 /*

--- 265 unchanged lines hidden ---