/*
This file is part of BOP.
Copyright (C) 2004 Patrick Davalan
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The GNU General Public License text is also available at
http://www.gnu.org/
or on the Copyright holder web site :
http://patrick.davalan.free.fr/gnu-gpl.html
*/
// substitute #include <bop.h> when bop is installed
#define DEBUG 0
// change the include to #include <bop.2/bop.h>
#include "bop.h"
#include "bopmakeh.h"
//
// This function fills a hash from the the lines of a file
// It is intended to serve as en example to use the bop API.
//
// This function expect that each line of the input file is a word
// followed by a new-line, what is a word is up to you.
//
int
bopMakeH(BophHandle *hash, char * wordFileName)
{
// Read a file and for each word which appears in, update a count.
// the first time the word appears, it is put in a hash
// with a count of 1, the next times, this count is incremented.
//
// return true or abort on failure.
//
FILE * wordFile ;
#define BUFSIZE 4096
char name[BUFSIZE] ;
BophEntry * hEntry ;
unsigned long wordRead = 0 ;
unsigned long wordAdded = 0 ;
bopdEnter( ) ;
bopdTrace( "hash at %p\n", hash ) ;
wordFile = bopxFopen( wordFileName, "r" ) ; // fopen or abort
// for each line of the input file
for ( ; fgets( name, BUFSIZE, wordFile ) != NULL ; )
{
size_t len = 0 ;
unsigned long count = 0 ;
unsigned long * hCount ;
wordRead++ ;
len = strlen(name) ;
*( name + len - 1 ) = 0 ; // erase \n
// len is the string length + 1 for the 0 char which we want to be
// stored in the hash
// here we will use the powerfulness of the flag BOPH_TEST :
// if the entry is not in the hash, the entry will be added
// to the hash and returned.
// if this entry is in the hash, the already existing entry
// will be returned.
// Anyway the entry, added or not, will be returned
//
// This is better than getting an entry, add a new one if not
// found or replace it, which implies 2 access to the entry.
//
hEntry = bophPut(hash, name, len, &count, sizeof(count), BOPH_TEST ) ;
//
// We have to increment the count of an existing entry or
// set the count of a new entry to 1.
// thus, we tried to add an entry with a zero count so that,
// was the entry already in the hash or not, we just have to
// increment the count afterward.
// get the address of count
hCount = (unsigned long *) bophGetData( hEntry ) ;
if ( (*hCount) == 0 ) wordAdded++ ;
// the entry returned is the address of the entry in the hash,
// not a copy. So, we can update it in place.
(*hCount)++ ; // update the entry in place
}
bopdTrace( "words added : %ld / ", wordAdded );
bopdTrace( "words read : %ld\n", wordRead );
bopxFclose( wordFile ) ;
bopdReturn( true ) ;
return( true ) ;
}