source: trunk/lib_c/hash.h @ 4051

Last change on this file since 4051 was 3391, checked in by linmengl, 6 years ago

check in IDISA C library and other support libraries. Some template features still remain.

File size: 5.6 KB
Line 
1/* Generated by cpp2c.rb from ./hash.hpp
2 * Use IDISA C support
3*/
4
5#ifndef HASH_H
6#define HASH_H
7
8/*=============================================================================
9  hash.hpp - Hash Utilities.
10  Created on: 18-December-2011
11  Author: Ken Herdy
12=============================================================================*/
13
14// #define HASH_HPP_DEBUG
15
16//#define NDEBUG // if NDEBUG then disable assertions
17
18#include "bitblock.h"
19#include <cassert>
20#include <stdint.h>
21#include <iostream>
22
23///////////////////////////////////////////////////////////////////////////////
24//
25// WARNING: Pad or Perish
26//
27// 'bit_slice' and 'byte_slice' slice forward via a static cast to the
28// uint64_t type at the position of the base address + bit_idx
29// and require up to sizeof(uint64_t) bytes of additional padding.
30//
31///////////////////////////////////////////////////////////////////////////////
32
33static int32_t bytes2bits(int32_t bytes) { return bytes * 8; }
34static int32_t bits2bytes(int32_t bits) /*{ return (bits + 8) / (8); } */ { return ((bits & (8-1) != 0) ? (bits + 8) / (8) : (bits/8)); }
35static IDISA_ALWAYS_INLINE uint64_t gen_mask(const uint32_t mask_bits);
36
37//static IDISA_ALWAYS_INLINE uint64_t byte_slice(const uint8_t * base, const int32_t byte_idx, const uint32_t slice_bytes);
38//static IDISA_ALWAYS_INLINE uint64_t byte_compress_hash(const uint8_t * h0, const uint8_t * h1, const int32_t byte_idx, const uint32_t slice_bytes, const uint32_t hash_bytes);
39
40static IDISA_ALWAYS_INLINE uint64_t bit_slice(const uint8_t * base, const int32_t bit_idx, const uint32_t slice_bits);
41static IDISA_ALWAYS_INLINE uint64_t bit_compress_hash(const uint8_t * h0, const uint8_t * h1, const int32_t bit_idx, const uint32_t slice_bits, const uint32_t hash_bits);
42
43///////////////////////////////////////////////////////////////////////////////
44
45static IDISA_ALWAYS_INLINE uint64_t gen_mask(const uint32_t mask_bits) {
46    assert(mask_bits >= 0);
47
48    const uint64_t ONE = 1;
49    uint64_t mask = (ONE << mask_bits) - ONE;
50#ifdef HASH_H_DEBUG
51    print_register<uint64_t>("mask", mask);
52#endif
53    return mask;
54}
55
56//static IDISA_ALWAYS_INLINE uint64_t byte_slice(const uint8_t * base, const int32_t byte_idx, const uint32_t slice_bytes) {
57//    assert(slice_bytes >= 0 && slice_bytes <= sizeof(uint64_t));
58//    assert(byte_idx >= 0);
59
60//    uint64_t shift = *((uint64_t *)(base + byte_idx));
61//    uint64_t mask = gen_mask(bytes2bits(slice_bytes));
62//    uint64_t r = shift & mask;
63
64//#ifdef HASH_HPP_DEBUG
65//    print_register<BitBlock>("base", *(BitBlock *)base);
66//    std::cout << "byte index:" << byte_idx << std::endl;
67//    print_register<BitBlock>("shift", *(BitBlock *)&shift);
68//    print_register<uint64_t>("mask", mask);
69//    print_register<uint64_t>("r", r);
70//#endif
71
72//    return r;
73//}
74
75static IDISA_ALWAYS_INLINE uint64_t bit_slice(const uint8_t * base, const int32_t bit_idx, const uint32_t slice_bits) {
76    assert(slice_bits >= 0 && slice_bits <= bytes2bits(sizeof(uint64_t)));
77    assert(bit_idx >= 0);
78
79    uint64_t shift = *((uint64_t *)(base + (bit_idx/8))) >> (bit_idx & (8-1));
80    uint64_t mask = gen_mask(slice_bits);
81    uint64_t r = shift & mask;
82
83#ifdef HASH_H_DEBUG
84    print_register<uint64_t>("base", *(uint64_t *)base);
85    std::cout << "           bit index = " << bit_idx << std::endl;
86    print_register<uint64_t>("shift", *(uint64_t *)&shift);
87    print_register<uint64_t>("mask", mask);
88    print_register<uint64_t>("r", r);
89#endif
90
91    return r;
92}
93
94static IDISA_ALWAYS_INLINE uint64_t bit_compress_hash(const uint8_t * h0, const uint8_t * h1, const int32_t bit_idx, const uint32_t slice_bits, const uint32_t hash_bits) {
95
96    assert(hash_bits > 0 && hash_bits <= 64);
97    assert(slice_bits >= hash_bits);
98
99    uint64_t x0 = bit_slice(h0,bit_idx,hash_bits);
100    uint64_t x1 = bit_slice(h1,bit_idx+slice_bits-hash_bits,hash_bits);
101
102    //assert(x0 != x1);
103    uint64_t mask = gen_mask(slice_bits);
104    uint64_t r = x0 ^ x1;
105
106#ifdef HASH_H_DEBUG
107    print_register<uint64_t>("h0", *(uint64_t *)(h0));
108    print_register<uint64_t>("h1", *(uint64_t *)(h1));
109    print_register<uint64_t>("x0", x0);
110    print_register<uint64_t>("x1", x1);
111    print_register<uint64_t>("r", r);
112#endif
113
114    return r  & mask;
115}
116
117#endif // HASH_H
118
119/*
120static IDISA_ALWAYS_INLINE uint64_t bit_expand_hash(const uint8_t * base, const uint8_t * base1, const int32_t offset, const uint32_t slice_size, const uint32_t hash_size);
121static IDISA_ALWAYS_INLINE uint64_t bit_expand_hash(const uint8_t * base, const uint8_t * base1, const int32_t offset, const uint32_t slice_size, const uint32_t hash_size) {
122    assert(slice_size > 0 && slice_size <= 64);
123    //assert(slice_size <= hash_size);
124
125    uint64_t x0 = bit_slice(base,offset,slice_size);
126    uint64_t x1 = bit_slice(base1,offset,slice_size);
127    uint64_t mask = gen_mask(hash_size);
128
129    assert(x0 != x1);
130
131    uint64_t t = x0 ^ x1;
132    uint64_t r = t;
133    int32_t shift = slice_size;
134
135    print_register<uint64_t>("t", t);
136    print_register<uint64_t>("r", r);
137
138    while(shift > 0) {
139
140#ifndef NDEBUG
141    std::cout << "Stream offset (bit):  " << offset << std::endl;
142    std::cout << "Symbol lgth (bits): " << slice_size << std::endl;
143    std::cout << "Hash size (bits):   " << hash_size << std::endl;
144    std::cout << "Shift (bits): " << shift << std::endl;
145
146    print_register<uint64_t>("base", *(uint64_t *)base);
147    print_register<uint64_t>("base1", *(uint64_t *)base1);
148    print_register<uint64_t>("x0", x0);
149    print_register<uint64_t>("x1", x1);
150    print_register<uint64_t>("r", r);
151#endif
152        r = r | (r << (uint32_t)shift);
153        shift -= slice_size;
154        print_register<uint64_t>("r", r);
155    }
156
157    return r & mask;
158}
159*/
160
Note: See TracBrowser for help on using the repository browser.