about summary refs log tree commit diff stats
path: root/077hash.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-02-17 10:29:40 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-02-17 10:29:40 -0800
commit37e717859c47a86754e1d2d33865513a7c16dcb0 (patch)
tree8261b16d12cdc920c3f86cefe8532756253a9c2f /077hash.cc
parent3adc9e08715fb695b8a7f53d5cfb3db1bd434b05 (diff)
downloadmu-37e717859c47a86754e1d2d33865513a7c16dcb0.tar.gz
2668 - add an escape hatch for 'hash'
If you don't want a field of a container to be included in its hash, use
the /ignore-for-hash property.

This property only works for containers, not exclusive-containers or
arrays. Mu will warn if you misuse it.
Diffstat (limited to '077hash.cc')
-rw-r--r--077hash.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/077hash.cc b/077hash.cc
index f2cc403d..d5e45095 100644
--- a/077hash.cc
+++ b/077hash.cc
@@ -101,6 +101,7 @@ size_t hash_mu_container(size_t h, const reagent& r) {
   long long int offset = 0;
   for (long long int i = 0; i < SIZE(info.elements); ++i) {
     reagent element = element_type(r, i);
+    if (has_property(element, "ignore-for-hash")) continue;
     element.set_value(address+offset);
     h = hash(h, element);
 //?     cerr << i << ": " << h << '\n';
@@ -119,6 +120,9 @@ size_t hash_mu_exclusive_container(size_t h, const reagent& r) {
   assert(r.type->value);
   long long int tag = get(Memory, r.value);
   reagent variant = variant_type(r, tag);
+  // todo: move this warning to container definition time
+  if (has_property(variant, "ignore-for-hash"))
+    raise << get(Type, r.type->value).name << ": /ignore-for-hash won't work in exclusive containers\n";
   variant.set_value(r.value + /*skip tag*/1);
   h = hash(h, variant);
   return h;
@@ -173,6 +177,23 @@ recipe main [
 # hash on containers includes all elements
 +mem: storing 0 in location 9
 
+:(scenario hash_can_ignore_container_elements)
+container foo [
+  x:number
+  y:character/ignore-for-hash
+]
+recipe main [
+  1:foo <- merge 34, 97/a
+  3:number <- hash 1:foo
+  reply-unless 3:number
+  4:foo <- merge 34, 98/a
+  6:number <- hash 4:foo
+  reply-unless 6:number
+  7:boolean <- equal 3:number, 6:number
+]
+# hashes match even though y is different
++mem: storing 1 in location 7
+
 //: These properties aren't necessary for hash, they just test that the
 //: current implementation works like we think it does.
 
eck_type_by_instruction.cc?h=main&id=4e49b29e63b0d369b81318ac822dc06ce06786b5'>4e49b29e ^
d855b0a0 ^
4e49b29e ^

a0d7a155 ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115