Skip to content

Commit ccc7201

Browse files
committed
Add flag to enable/disable type reduction
1 parent bc262f8 commit ccc7201

10 files changed

Lines changed: 396 additions & 3 deletions

Src/FastData.Generator/Framework/OutputWriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ protected string GetEqualFunction(string value1, string value2, KeyType keyTypeO
9292

9393
protected string ToValueLabel<T>(T value) => _typeMap.ToValueLabel(value); //Uses its own generics here, not TKey. We need T so we can change the type in generators
9494
protected string GetObjectDeclarations<TValue>() => typeof(TValue).IsPrimitive ? "" : _typeMap.GetDeclarations<TValue>(); //We don't have declarations for primitives
95-
protected string GetSmallestSignedType(long value) => _typeMap.GetSmallestIntType(value);
96-
protected string GetSmallestUnsignedType(long value) => _typeMap.GetSmallestUIntType((ulong)value);
95+
protected string GetSmallestSignedType(long value) => _generatorConfig.TypeReductionEnabled ? _typeMap.GetSmallestIntType(value) : _typeMap.Get<int>().Name;
96+
protected string GetSmallestUnsignedType(long value) => _generatorConfig.TypeReductionEnabled ? _typeMap.GetSmallestUIntType((ulong)value) : _typeMap.Get<uint>().Name;
9797

9898
private static IEnumerable<string> GetValues(Array array, TypeMap map, Type type)
9999
{

Src/FastData.TestHarness.Runner/FeatureTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,26 @@ public async Task PrefixSuffixTrimming(ITestHarness harness, bool ignoreCase)
6969
int exitCode = TestHarnessRunnerHelper.RunContainsProgram(harness, spec, lookups, notPresent, className);
7070
TestHarnessRunnerHelper.AssertSuccessExitCode(exitCode);
7171
}
72+
73+
[Theory]
74+
[ClassData(typeof(HarnessBoolTheoryData))]
75+
public async Task TypeReductionEnabled(ITestHarness harness, bool typeReductionEnabled)
76+
{
77+
FastDataConfig config = new FastDataConfig(StructureType.HashTable)
78+
{
79+
TypeReductionEnabled = typeReductionEnabled
80+
};
81+
82+
string className = $"{nameof(TypeReductionEnabled)}_{typeReductionEnabled}";
83+
byte[] keys = [byte.MinValue, 1, byte.MaxValue];
84+
85+
string source = FastDataGenerator.Generate(keys, config, harness.CreateGenerator(className));
86+
GeneratorSpec spec = new GeneratorSpec(className, source);
87+
88+
await TestHarnessRunnerHelper.VerifyFeatureAsync(harness, className, spec.Source);
89+
90+
byte[] notPresent = [2, 4];
91+
int exitCode = TestHarnessRunnerHelper.RunContainsProgram(harness, spec, keys, notPresent, className);
92+
TestHarnessRunnerHelper.AssertSuccessExitCode(exitCode);
93+
}
7294
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// This file is auto-generated. Do not edit manually.
2+
// Structure: HashTable
3+
#pragma once
4+
#include <array>
5+
#include <cstring>
6+
#include <cstdint>
7+
#include <limits>
8+
#include <string_view>
9+
10+
class TypeReductionEnabled_False final {
11+
struct e {
12+
uint8_t key;
13+
int32_t next;
14+
15+
16+
e(const uint8_t key, const int32_t next)
17+
: key(key), next(next) {}
18+
};
19+
20+
static constexpr std::array<int32_t, 3> buckets = {
21+
3, 2, 0
22+
};
23+
24+
inline static const std::array<e, 3> entries = {
25+
e(0, -1), e(1, -1), e(std::numeric_limits<uint8_t>::max(), 0)
26+
};
27+
28+
static constexpr uint64_t get_hash(const uint8_t value) noexcept
29+
{
30+
return static_cast<uint64_t>(value);
31+
}
32+
33+
public:
34+
[[nodiscard]]
35+
static constexpr bool contains(const uint8_t key) noexcept {
36+
if (key < 0 || key > std::numeric_limits<uint8_t>::max())
37+
return false;
38+
39+
40+
const uint64_t hash = get_hash(key);
41+
const size_t index = hash % 3;
42+
int32_t i = static_cast<int32_t>(buckets[index] - 1);
43+
44+
while (i >= 0) {
45+
const auto& entry = entries[i];
46+
47+
if (entry.key == key)
48+
return true;
49+
50+
i = entry.next;
51+
}
52+
53+
return false;
54+
}
55+
56+
static constexpr size_t item_count = 3;
57+
static constexpr uint8_t min_key = 0;
58+
static constexpr uint8_t max_key = std::numeric_limits<uint8_t>::max();
59+
};
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// This file is auto-generated. Do not edit manually.
2+
// Structure: HashTable
3+
#pragma once
4+
#include <array>
5+
#include <cstring>
6+
#include <cstdint>
7+
#include <limits>
8+
#include <string_view>
9+
10+
class TypeReductionEnabled_True final {
11+
struct e {
12+
uint8_t key;
13+
int8_t next;
14+
15+
16+
e(const uint8_t key, const int8_t next)
17+
: key(key), next(next) {}
18+
};
19+
20+
static constexpr std::array<int8_t, 3> buckets = {
21+
3, 2, 0
22+
};
23+
24+
inline static const std::array<e, 3> entries = {
25+
e(0, -1), e(1, -1), e(std::numeric_limits<uint8_t>::max(), 0)
26+
};
27+
28+
static constexpr uint64_t get_hash(const uint8_t value) noexcept
29+
{
30+
return static_cast<uint64_t>(value);
31+
}
32+
33+
public:
34+
[[nodiscard]]
35+
static constexpr bool contains(const uint8_t key) noexcept {
36+
if (key < 0 || key > std::numeric_limits<uint8_t>::max())
37+
return false;
38+
39+
40+
const uint64_t hash = get_hash(key);
41+
const size_t index = hash % 3;
42+
int8_t i = static_cast<int8_t>(buckets[index] - 1);
43+
44+
while (i >= 0) {
45+
const auto& entry = entries[i];
46+
47+
if (entry.key == key)
48+
return true;
49+
50+
i = entry.next;
51+
}
52+
53+
return false;
54+
}
55+
56+
static constexpr size_t item_count = 3;
57+
static constexpr uint8_t min_key = 0;
58+
static constexpr uint8_t max_key = std::numeric_limits<uint8_t>::max();
59+
};
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// <auto-generated />
2+
// This file is auto-generated. Do not edit manually.
3+
// Structure: HashTable
4+
#nullable enable
5+
using System;
6+
using System.Runtime.CompilerServices;
7+
using System.Runtime.InteropServices;
8+
9+
internal static class TypeReductionEnabled_False
10+
{
11+
[StructLayout(LayoutKind.Auto)]
12+
private struct E
13+
{
14+
internal byte Key;
15+
internal int Next;
16+
17+
18+
internal E(byte key, int next )
19+
{
20+
Key = key;
21+
Next = next;
22+
23+
24+
}
25+
};
26+
27+
private static readonly int[] _buckets = new int[] {
28+
3, 2, 0
29+
};
30+
31+
private static readonly E[] _entries = {
32+
new E(byte.MinValue, -1), new E(1, -1), new E(byte.MaxValue, 0)
33+
};
34+
35+
36+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
37+
private static ulong Hash(byte value)
38+
{
39+
return (ulong)value;
40+
}
41+
42+
43+
public static bool Contains(byte key)
44+
{
45+
if (key < byte.MinValue || key > byte.MaxValue)
46+
return false;
47+
48+
49+
ulong hash = Hash(key);
50+
uint index = (uint)(hash % 3);
51+
int i = (int)(_buckets[index] - 1);
52+
53+
while (i >= 0)
54+
{
55+
ref E entry = ref _entries[i];
56+
57+
if (entry.Key == key)
58+
return true;
59+
60+
i = entry.Next;
61+
}
62+
63+
return false;
64+
}
65+
66+
public const uint ItemCount = 3;
67+
public const byte MinKey = byte.MinValue;
68+
public const byte MaxKey = byte.MaxValue;
69+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// <auto-generated />
2+
// This file is auto-generated. Do not edit manually.
3+
// Structure: HashTable
4+
#nullable enable
5+
using System;
6+
using System.Runtime.CompilerServices;
7+
using System.Runtime.InteropServices;
8+
9+
internal static class TypeReductionEnabled_True
10+
{
11+
[StructLayout(LayoutKind.Auto)]
12+
private struct E
13+
{
14+
internal byte Key;
15+
internal sbyte Next;
16+
17+
18+
internal E(byte key, sbyte next )
19+
{
20+
Key = key;
21+
Next = next;
22+
23+
24+
}
25+
};
26+
27+
private static readonly sbyte[] _buckets = new sbyte[] {
28+
3, 2, 0
29+
};
30+
31+
private static readonly E[] _entries = {
32+
new E(byte.MinValue, -1), new E(1, -1), new E(byte.MaxValue, 0)
33+
};
34+
35+
36+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
37+
private static ulong Hash(byte value)
38+
{
39+
return (ulong)value;
40+
}
41+
42+
43+
public static bool Contains(byte key)
44+
{
45+
if (key < byte.MinValue || key > byte.MaxValue)
46+
return false;
47+
48+
49+
ulong hash = Hash(key);
50+
uint index = (uint)(hash % 3);
51+
sbyte i = (sbyte)(_buckets[index] - 1);
52+
53+
while (i >= 0)
54+
{
55+
ref E entry = ref _entries[i];
56+
57+
if (entry.Key == key)
58+
return true;
59+
60+
i = entry.Next;
61+
}
62+
63+
return false;
64+
}
65+
66+
public const uint ItemCount = 3;
67+
public const byte MinKey = byte.MinValue;
68+
public const byte MaxKey = byte.MaxValue;
69+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! This file is auto-generated. Do not edit manually.
2+
//! Structure: HashTable
3+
#![allow(unused_parens)]
4+
#![allow(missing_docs)]
5+
#![allow(unused_imports)]
6+
#![allow(unused_unsafe)]
7+
use std::ptr;
8+
9+
pub struct TypeReductionEnabled_False;
10+
11+
impl TypeReductionEnabled_False {
12+
const BUCKETS: [i32; 3] = [
13+
3, 2, 0
14+
];
15+
16+
const ENTRIES: [E; 3] = [
17+
E { next: -1, key: u8::MIN }, E { next: -1, key: 1 }, E { next: 0, key: u8::MAX }
18+
];
19+
20+
#[inline(always)]
21+
fn get_hash(value: u8) -> u64 {
22+
value as u64
23+
}
24+
25+
#[must_use]
26+
pub fn contains(key: u8) -> bool {
27+
if key < u8::MIN || key > u8::MAX {
28+
return false;
29+
}
30+
31+
32+
let hash = unsafe { Self::get_hash(key) };
33+
let index = hash % 3;
34+
let mut i: i32 = (Self::BUCKETS[index as usize] as i32) - 1;
35+
36+
while i >= 0 {
37+
let entry = &Self::ENTRIES[i as usize];
38+
if entry.key == key {
39+
return true;
40+
}
41+
i = entry.next;
42+
}
43+
44+
false
45+
}
46+
47+
pub const ITEM_COUNT: usize = 3;
48+
pub const MIN_KEY: u8 = u8::MIN;
49+
pub const MAX_KEY: u8 = u8::MAX;
50+
}struct E {
51+
52+
next: i32,
53+
key: u8,
54+
55+
}

0 commit comments

Comments
 (0)