Created
November 19, 2016 06:46
-
-
Save vmxdev/3f81581eea9add508d79c1f8fd16de5c to your computer and use it in GitHub Desktop.
t1ha hash function map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <png.h> | |
#include <stdint.h> | |
#include "t1ha.h" | |
#define STRLEN 10 | |
#define NITER 1000000 | |
/*#define SQRSIDE 842*/ | |
#define SQRSIDE 800 | |
/* A coloured pixel. */ | |
typedef struct { | |
uint8_t red; | |
uint8_t green; | |
uint8_t blue; | |
} pixel_t; | |
/* A picture. */ | |
typedef struct { | |
pixel_t *pixels; | |
size_t width; | |
size_t height; | |
} bitmap_t; | |
static pixel_t * | |
pixel_at (bitmap_t * bitmap, int x, int y) | |
{ | |
return bitmap->pixels + bitmap->width * y + x; | |
} | |
static int | |
save_png_to_file(bitmap_t *bitmap, const char *path) | |
{ | |
FILE * fp; | |
png_structp png_ptr = NULL; | |
png_infop info_ptr = NULL; | |
size_t x, y; | |
png_byte ** row_pointers = NULL; | |
/* "status" contains the return value of this function. At first | |
it is set to a value which means 'failure'. When the routine | |
has finished its work, it is set to a value which means | |
'success'. */ | |
int status = -1; | |
/* The following number is set by trial and error only. I cannot | |
see where it it is documented in the libpng manual. | |
*/ | |
int pixel_size = 3; | |
int depth = 8; | |
fp = fopen (path, "wb"); | |
if (!fp) { | |
goto fopen_failed; | |
} | |
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | |
if (png_ptr == NULL) { | |
goto png_create_write_struct_failed; | |
} | |
info_ptr = png_create_info_struct (png_ptr); | |
if (info_ptr == NULL) { | |
goto png_create_info_struct_failed; | |
} | |
/* Set up error handling. */ | |
if (setjmp(png_jmpbuf(png_ptr))) { | |
goto png_failure; | |
} | |
/* Set image attributes. */ | |
png_set_IHDR(png_ptr, | |
info_ptr, | |
bitmap->width, | |
bitmap->height, | |
depth, | |
PNG_COLOR_TYPE_RGB, | |
PNG_INTERLACE_NONE, | |
PNG_COMPRESSION_TYPE_DEFAULT, | |
PNG_FILTER_TYPE_DEFAULT); | |
/* Initialize rows of PNG. */ | |
row_pointers = png_malloc(png_ptr, bitmap->height * sizeof(png_byte *)); | |
for (y=0; y<bitmap->height; y++) { | |
png_byte *row = | |
png_malloc (png_ptr, | |
sizeof (uint8_t) * bitmap->width * pixel_size); | |
row_pointers[y] = row; | |
for (x=0; x<bitmap->width; x++) { | |
pixel_t * pixel = pixel_at(bitmap, x, y); | |
*row++ = pixel->red; | |
*row++ = pixel->green; | |
*row++ = pixel->blue; | |
} | |
} | |
/* Write the image data to "fp". */ | |
png_init_io(png_ptr, fp); | |
png_set_rows(png_ptr, info_ptr, row_pointers); | |
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); | |
/* The routine has successfully written the file, so we set | |
"status" to a value which indicates success. */ | |
status = 0; | |
for (y=0; y<bitmap->height; y++) { | |
png_free(png_ptr, row_pointers[y]); | |
} | |
png_free(png_ptr, row_pointers); | |
png_failure: | |
png_create_info_struct_failed: | |
png_destroy_write_struct(&png_ptr, &info_ptr); | |
png_create_write_struct_failed: | |
fclose (fp); | |
fopen_failed: | |
return status; | |
} | |
static void | |
mkstr(char *data) | |
{ | |
int i; | |
for (i=0; i<STRLEN-1; i++) { | |
data[i] = rand() % 10 + '0'; | |
} | |
data[STRLEN-1] = '\0'; | |
} | |
int | |
main() | |
{ | |
char data[STRLEN]; | |
int i; | |
uint64_t h; | |
uint64_t *map, maxc; | |
bitmap_t img; | |
uint32_t x, y; | |
map = calloc(sizeof(uint64_t), SQRSIDE * SQRSIDE); | |
maxc = 0; | |
img.width = SQRSIDE; | |
img.height = SQRSIDE; | |
img.pixels = calloc(img.width * img.height, sizeof(pixel_t)); | |
for (i=0; i<NITER; i++) { | |
mkstr(data); | |
h = t1ha(data, STRLEN, 1); | |
/*printf("%s: %lu\n", data, h);*/ | |
x = (uint32_t)h; | |
y = h >> 32; | |
x = (uint64_t)x * SQRSIDE / UINT32_MAX; | |
y = (uint64_t)y * SQRSIDE / UINT32_MAX; | |
map[x + y * SQRSIDE]++; | |
maxc = maxc < map[x + y * SQRSIDE] ? map[x + y * SQRSIDE] : maxc; | |
} | |
for (x=0; x<SQRSIDE; x++) { | |
for (y=0; y<SQRSIDE; y++) { | |
pixel_t *p = pixel_at(&img, x, y); | |
if (map[x + y * SQRSIDE]) { | |
p->red = p->green = p->blue = 0; | |
} else { | |
p->red = p->green = p->blue = 200; | |
} | |
} | |
} | |
save_png_to_file(&img, "hashmap.png"); | |
free(img.pixels); | |
free(map); | |
printf("maxc: %lu\n", maxc); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment