Repository navigation
Expand file tree
/
Copy pathservable_id.h
More file actions
100 lines (83 loc) · 3.5 KB
/
Copy pathservable_id.h
File metadata and controls
100 lines (83 loc) · 3.5 KB
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
/* Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_SERVING_CORE_SERVABLE_ID_H_
#define TENSORFLOW_SERVING_CORE_SERVABLE_ID_H_
#include <iosfwd>
#include <string>
#include <unordered_map>
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow_serving/util/hash.h"
namespace tensorflow {
namespace serving {
// An identifier for a Servable. Two Servable objects with the
// same identifier are considered semantically equivalent (modulo its loaded-
// ness state).
struct ServableId {
// The name of the servable stream to which this servable object belongs.
string name;
// The sequence number of this servable object in its stream. The primary
// purpose of 'version' is to uniquely identify a servable object. A
// secondary purpose is to support inbound requests that identify just a
// servable stream name but not a specific version; those are routed to the
// active servable with the largest version number.
//
// Must be non-negative.
int64 version;
// Returns a string representation of this object. Useful in logging.
string DebugString() const {
return strings::StrCat("{name: ", name, " version: ", version, "}");
}
};
struct HashServableId {
uint64 operator()(const ServableId& id) const {
// Hash codes for many common types are remarkably bad, often clustering
// around the same values of the low and/or high bits for linear
// sequences of inputs such as 1, 2, 3; or addresses of consecutively
// allocated objects. For these cases the default hash function is the
// identity function on the bit patterns.
//
// So we apply a one-to-one mapping to the resulting bit patterns to
// make the high bits contain more entropy from the entire hash code.
// It's based on Fibonacci hashing from Knuth's Art of Computer
// Programming volume 3, section 6.4.
const uint64 version_hash = [&]() -> uint64 {
if (id.version >= 0) {
return std::hash<int64>()(id.version) *
0x9E3779B97F4A7C13; // (sqrt(5) - 1)/2 as a binary fraction.
} else {
return 0xDECAFCAFFE;
}
}();
// Using version_hash as the seed here to combine the hashes.
return HashCombine(version_hash, std::hash<string>()(id.name));
}
};
inline bool operator==(const ServableId& a, const ServableId& b) {
return a.version == b.version && a.name == b.name;
}
inline bool operator!=(const ServableId& a, const ServableId& b) {
return !(a == b);
}
inline bool operator<(const ServableId& a, const ServableId& b) {
const int strcmp_result = a.name.compare(b.name);
if (strcmp_result != 0) {
return strcmp_result < 0;
}
return a.version < b.version;
}
inline std::ostream& operator<<(std::ostream& out, const ServableId& id) {
return out << id.DebugString();
}
} // namespace serving
} // namespace tensorflow
#endif // TENSORFLOW_SERVING_CORE_SERVABLE_ID_H_