nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

tables.h (4055B)


      1 STATIC uint64_t read_unaligned_u64(
      2     const unsigned char [static sizeof(uint64_t)]);
      3 STATIC void write_unaligned_u64(
      4     unsigned char [static sizeof(uint64_t)], uint64_t);
      5 STATIC int64_t readtableinfo(
      6     size_t, const unsigned char *, tableinfo_t [static 1]);
      7 STATIC int64_t readtableinfo_n(
      8     size_t, const unsigned char *, uint8_t, tableinfo_t [static 1]);
      9 STATIC int64_t writetableinfo(
     10     const tableinfo_t [static 1], size_t, unsigned char *);
     11 
     12 STATIC uint64_t
     13 read_unaligned_u64(const unsigned char buf[static sizeof(uint64_t)])
     14 {
     15 	uint64_t ret;
     16 
     17 	memcpy(&ret, buf, sizeof(uint64_t));
     18 
     19 	return ret;
     20 }
     21 
     22 STATIC void
     23 write_unaligned_u64(unsigned char buf[static sizeof(uint64_t)], uint64_t x)
     24 {
     25 	memcpy(buf, &x, sizeof(uint64_t));
     26 }
     27 
     28 STATIC int64_t
     29 readtableinfo(
     30 	size_t buf_size,
     31 	const unsigned char *buf,
     32 	tableinfo_t info[static 1]
     33 )
     34 {
     35 	size_t i;
     36 
     37 	if (buf == NULL) {
     38 		LOG("Error reading table: buffer is NULL\n");
     39 		return NISSY_ERROR_NULL_POINTER;
     40 	}
     41 
     42 	if (buf_size < INFOSIZE) {
     43 		LOG("Error reading table: buffer size is too small "
     44 		    "(given size %zu is smaller than INFOSIZE = %"
     45 		    PRId64 ")\n", buf_size, INFOSIZE);
     46 		return NISSY_ERROR_BUFFER_SIZE;
     47 	}
     48 
     49 	for (i = 0; i < INFO_DISTRIBUTION_LEN; i++)
     50 		info->distribution[i] = read_unaligned_u64(OFFSET(buf,
     51 		    INFO_OFFSET_DISTRIBUTION + i * sizeof(uint64_t)));
     52 
     53 	info->type = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_TYPE));
     54 	info->infosize = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_INFOSIZE));
     55 	info->fullsize = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_FULLSIZE));
     56 	info->hash = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_HASH));
     57 	info->entries = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_ENTRIES));
     58 	info->classes = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_CLASSES));
     59 	info->next = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_NEXT));
     60 
     61 	memcpy(info->solver, OFFSET(buf, INFO_OFFSET_SOLVER),
     62 	    INFO_SOLVER_STRLEN);
     63 
     64 	info->h48h = *(uint8_t *)OFFSET(buf, INFO_OFFSET_H48H);
     65 	info->bits = *(uint8_t *)OFFSET(buf, INFO_OFFSET_BITS);
     66 	info->base = *(uint8_t *)OFFSET(buf, INFO_OFFSET_BASE);
     67 	info->maxvalue = *(uint8_t *)OFFSET(buf, INFO_OFFSET_MAXVALUE);
     68 
     69 	return NISSY_OK;
     70 }
     71 
     72 STATIC int64_t
     73 readtableinfo_n(
     74 	size_t buf_size,
     75 	const unsigned char *buf,
     76 	uint8_t n,
     77 	tableinfo_t info[static 1]
     78 )
     79 {
     80 	int64_t ret;
     81 
     82 	for (; n > 0; n--, buf = buf + info->next, buf_size -= info->next)
     83 		if ((ret = readtableinfo(buf_size, buf, info)) != 0)
     84 			return ret;
     85 
     86 	return NISSY_OK;
     87 }
     88 
     89 STATIC int64_t
     90 writetableinfo(
     91 	const tableinfo_t info[static 1],
     92 	size_t data_size,
     93 	unsigned char *buf
     94 )
     95 {
     96 	size_t i;
     97 	bool end;
     98 	unsigned char *c;
     99 
    100 	if (data_size < info->fullsize) {
    101 		LOG("Error writing table: buffer size is too small "
    102 		    "(given %zu but table requires %" PRId64 ")\n",
    103 		    data_size, info->fullsize);
    104 		return NISSY_ERROR_BUFFER_SIZE;
    105 	}
    106 
    107 	for (i = 0; i < INFO_DISTRIBUTION_LEN; i++)
    108 		write_unaligned_u64(OFFSET(buf, INFO_OFFSET_DISTRIBUTION +
    109 		    i * sizeof(uint64_t)), info->distribution[i]);
    110 
    111 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_TYPE), info->type);
    112 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_INFOSIZE), info->infosize);
    113 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_FULLSIZE), info->fullsize);
    114 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_HASH), info->hash);
    115 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_ENTRIES), info->entries);
    116 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_CLASSES), info->classes);
    117 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_NEXT), info->next);
    118 
    119 	memcpy(OFFSET(buf, INFO_OFFSET_SOLVER), info->solver,
    120 	    INFO_SOLVER_STRLEN);
    121 
    122 	/* Zeroing all chars after the end of the string, for consistency */
    123 	end = false;
    124 	for (i = 0; i < INFO_SOLVER_STRLEN; i++) {
    125 		c = OFFSET(buf, INFO_OFFSET_SOLVER + i);
    126 		end = end || *c == 0;
    127 		if (end)
    128 			*c = 0;
    129 	}
    130 
    131 	*OFFSET(buf, INFO_OFFSET_H48H) = (unsigned char)info->h48h;
    132 	*OFFSET(buf, INFO_OFFSET_BITS) = (unsigned char)info->bits;
    133 	*OFFSET(buf, INFO_OFFSET_BASE) = (unsigned char)info->base;
    134 	*OFFSET(buf, INFO_OFFSET_MAXVALUE) = (unsigned char)info->maxvalue;
    135 
    136 	return NISSY_OK;
    137 }