whatap-python 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- whatap/LICENSE +0 -0
- whatap/README.rst +49 -0
- whatap/__init__.py +923 -0
- whatap/__main__.py +4 -0
- whatap/agent/darwin/amd64/whatap_python +0 -0
- whatap/agent/darwin/arm64/whatap_python +0 -0
- whatap/agent/linux/amd64/whatap_python +0 -0
- whatap/agent/linux/arm64/whatap_python +0 -0
- whatap/agent/windows/whatap_python.exe +0 -0
- whatap/bootstrap/__init__.py +0 -0
- whatap/bootstrap/sitecustomize.py +19 -0
- whatap/build.py +4 -0
- whatap/conf/__init__.py +0 -0
- whatap/conf/configuration.py +280 -0
- whatap/conf/configure.py +105 -0
- whatap/conf/license.py +49 -0
- whatap/control/__init__.py +0 -0
- whatap/counter/__init__.py +14 -0
- whatap/counter/counter_manager.py +45 -0
- whatap/counter/tasks/__init__.py +3 -0
- whatap/counter/tasks/base_task.py +26 -0
- whatap/counter/tasks/llm_evaluator_task.py +501 -0
- whatap/counter/tasks/llm_log_sink_task.py +309 -0
- whatap/counter/tasks/llm_stat_task.py +78 -0
- whatap/counter/tasks/openfiledescriptor.py +67 -0
- whatap/io/__init__.py +1 -0
- whatap/io/data_inputx.py +161 -0
- whatap/io/data_outputx.py +262 -0
- whatap/llm/__init__.py +17 -0
- whatap/llm/definitions.py +43 -0
- whatap/llm/evaluators/__init__.py +136 -0
- whatap/llm/evaluators/base.py +114 -0
- whatap/llm/evaluators/builtins/__init__.py +91 -0
- whatap/llm/evaluators/builtins/answer_relevance.py +46 -0
- whatap/llm/evaluators/builtins/combined_judge.py +271 -0
- whatap/llm/evaluators/builtins/factuality.py +71 -0
- whatap/llm/evaluators/builtins/hallucination.py +97 -0
- whatap/llm/evaluators/builtins/llm_judge.py +516 -0
- whatap/llm/evaluators/builtins/pii_leak.py +214 -0
- whatap/llm/evaluators/builtins/prompt_injection.py +71 -0
- whatap/llm/evaluators/builtins/toxicity.py +53 -0
- whatap/llm/evaluators/builtins/url_scan.py +194 -0
- whatap/llm/evaluators/registry.py +192 -0
- whatap/llm/evaluators/sampler.py +83 -0
- whatap/llm/evaluators/scope.py +334 -0
- whatap/llm/features.py +66 -0
- whatap/llm/log_sink_packs/__init__.py +9 -0
- whatap/llm/log_sink_packs/llm_input_message.py +16 -0
- whatap/llm/log_sink_packs/llm_log_sink_pack.py +72 -0
- whatap/llm/log_sink_packs/llm_output_message.py +19 -0
- whatap/llm/log_sink_packs/llm_step_eval_status.py +94 -0
- whatap/llm/log_sink_packs/llm_step_status.py +118 -0
- whatap/llm/log_sink_packs/llm_system_message.py +16 -0
- whatap/llm/log_sink_packs/llm_tool_calls.py +44 -0
- whatap/llm/log_sink_packs/llm_tool_results.py +16 -0
- whatap/llm/log_sink_packs/llm_tx_status.py +108 -0
- whatap/llm/pricing.py +236 -0
- whatap/llm/prompt_meta.py +288 -0
- whatap/llm/providers/__init__.py +0 -0
- whatap/llm/providers/anthropic/__init__.py +37 -0
- whatap/llm/providers/anthropic/messages/__init__.py +0 -0
- whatap/llm/providers/anthropic/messages/messages.py +70 -0
- whatap/llm/providers/anthropic/messages/messages_context.py +76 -0
- whatap/llm/providers/anthropic/messages/messages_extractor.py +126 -0
- whatap/llm/providers/interceptor.py +182 -0
- whatap/llm/providers/openai/__init__.py +133 -0
- whatap/llm/providers/openai/chat/__init__.py +0 -0
- whatap/llm/providers/openai/chat/chat.py +82 -0
- whatap/llm/providers/openai/chat/chat_context.py +78 -0
- whatap/llm/providers/openai/chat/chat_extractor.py +127 -0
- whatap/llm/providers/openai/completions/__init__.py +0 -0
- whatap/llm/providers/openai/completions/completions.py +70 -0
- whatap/llm/providers/openai/completions/completions_context.py +31 -0
- whatap/llm/providers/openai/completions/completions_extractor.py +61 -0
- whatap/llm/providers/openai/content_parser.py +41 -0
- whatap/llm/providers/openai/embeddings/__init__.py +0 -0
- whatap/llm/providers/openai/embeddings/embeddings.py +59 -0
- whatap/llm/providers/openai/embeddings/embeddings_context.py +25 -0
- whatap/llm/providers/openai/embeddings/embeddings_extractor.py +26 -0
- whatap/llm/providers/openai/responses/__init__.py +0 -0
- whatap/llm/providers/openai/responses/responses.py +70 -0
- whatap/llm/providers/openai/responses/responses_context.py +88 -0
- whatap/llm/providers/openai/responses/responses_extractor.py +126 -0
- whatap/llm/providers/stream_accumulator.py +73 -0
- whatap/llm/stats/__init__.py +35 -0
- whatap/llm/stats/active_stat.py +86 -0
- whatap/llm/stats/answer_relevance_eval_stat.py +10 -0
- whatap/llm/stats/api_status_stat.py +35 -0
- whatap/llm/stats/base_stat.py +107 -0
- whatap/llm/stats/combined_judge_eval_stat.py +11 -0
- whatap/llm/stats/error_stat.py +59 -0
- whatap/llm/stats/eval_stat.py +225 -0
- whatap/llm/stats/factuality_eval_stat.py +10 -0
- whatap/llm/stats/feature_stat.py +104 -0
- whatap/llm/stats/finish_stat.py +105 -0
- whatap/llm/stats/hallucination_eval_stat.py +10 -0
- whatap/llm/stats/meter.py +18 -0
- whatap/llm/stats/perf_stat.py +117 -0
- whatap/llm/stats/pii_leak_eval_stat.py +12 -0
- whatap/llm/stats/prompt_injection_eval_stat.py +10 -0
- whatap/llm/stats/token_usage_stat.py +133 -0
- whatap/llm/stats/toxicity_eval_stat.py +10 -0
- whatap/llm/stats/url_scan_eval_stat.py +12 -0
- whatap/net/__init__.py +0 -0
- whatap/net/async_sender.py +107 -0
- whatap/net/packet_enum.py +44 -0
- whatap/net/packet_type_enum.py +31 -0
- whatap/net/param_def.py +69 -0
- whatap/net/stackhelper.py +87 -0
- whatap/net/udp_session.py +394 -0
- whatap/net/udp_thread.py +54 -0
- whatap/pack/__init__.py +0 -0
- whatap/pack/logSinkPack.py +77 -0
- whatap/pack/pack.py +34 -0
- whatap/pack/pack_enum.py +41 -0
- whatap/pack/tagCountPack.py +61 -0
- whatap/scripts/__init__.py +208 -0
- whatap/trace/__init__.py +12 -0
- whatap/trace/mod/__init__.py +0 -0
- whatap/trace/mod/amqp/__init__.py +0 -0
- whatap/trace/mod/amqp/kombu.py +122 -0
- whatap/trace/mod/amqp/pika.py +62 -0
- whatap/trace/mod/application/__init__.py +0 -0
- whatap/trace/mod/application/bottle.py +34 -0
- whatap/trace/mod/application/celery.py +81 -0
- whatap/trace/mod/application/cherrypy.py +30 -0
- whatap/trace/mod/application/django.py +287 -0
- whatap/trace/mod/application/django_asgi.py +266 -0
- whatap/trace/mod/application/django_py3.py +251 -0
- whatap/trace/mod/application/fastapi/__init__.py +31 -0
- whatap/trace/mod/application/fastapi/endpoint.py +73 -0
- whatap/trace/mod/application/fastapi/exception_log.py +63 -0
- whatap/trace/mod/application/fastapi/instrumentation.py +204 -0
- whatap/trace/mod/application/fastapi/scope.py +115 -0
- whatap/trace/mod/application/fastapi/transaction.py +67 -0
- whatap/trace/mod/application/flask.py +52 -0
- whatap/trace/mod/application/frappe.py +224 -0
- whatap/trace/mod/application/graphql.py +170 -0
- whatap/trace/mod/application/nameko.py +39 -0
- whatap/trace/mod/application/odoo.py +63 -0
- whatap/trace/mod/application/starlette.py +126 -0
- whatap/trace/mod/application/tornado.py +163 -0
- whatap/trace/mod/application/wsgi.py +195 -0
- whatap/trace/mod/database/__init__.py +0 -0
- whatap/trace/mod/database/cxoracle.py +49 -0
- whatap/trace/mod/database/mongo.py +169 -0
- whatap/trace/mod/database/mysql.py +80 -0
- whatap/trace/mod/database/neo4j.py +90 -0
- whatap/trace/mod/database/psycopg2.py +45 -0
- whatap/trace/mod/database/psycopg3.py +359 -0
- whatap/trace/mod/database/redis.py +122 -0
- whatap/trace/mod/database/sqlalchemy.py +213 -0
- whatap/trace/mod/database/sqlite3.py +130 -0
- whatap/trace/mod/database/util.py +630 -0
- whatap/trace/mod/email/__init__.py +0 -0
- whatap/trace/mod/email/smtp.py +78 -0
- whatap/trace/mod/httpc/__init__.py +0 -0
- whatap/trace/mod/httpc/django.py +31 -0
- whatap/trace/mod/httpc/httplib.py +70 -0
- whatap/trace/mod/httpc/httpx.py +62 -0
- whatap/trace/mod/httpc/requests.py +20 -0
- whatap/trace/mod/httpc/urllib3.py +27 -0
- whatap/trace/mod/httpc/util.py +388 -0
- whatap/trace/mod/logging.py +161 -0
- whatap/trace/mod/plugin.py +84 -0
- whatap/trace/mod/standalone/__init__.py +0 -0
- whatap/trace/mod/standalone/multiple.py +293 -0
- whatap/trace/mod/standalone/single.py +135 -0
- whatap/trace/simple_trace_context.py +18 -0
- whatap/trace/trace_context.py +212 -0
- whatap/trace/trace_context_manager.py +244 -0
- whatap/trace/trace_error.py +84 -0
- whatap/trace/trace_handler.py +89 -0
- whatap/trace/trace_import.py +91 -0
- whatap/trace/trace_module_definition.py +156 -0
- whatap/util/__init__.py +0 -0
- whatap/util/bit_util.py +49 -0
- whatap/util/cardinality/__init__.py +0 -0
- whatap/util/cardinality/hyperloglog.py +84 -0
- whatap/util/cardinality/murmurhash.py +20 -0
- whatap/util/cardinality/registerset.py +60 -0
- whatap/util/compare_util.py +19 -0
- whatap/util/date_util.py +55 -0
- whatap/util/debug_util.py +73 -0
- whatap/util/escape_literal_sql.py +233 -0
- whatap/util/frame_util.py +20 -0
- whatap/util/hash_util.py +103 -0
- whatap/util/hexa32.py +66 -0
- whatap/util/int_set.py +199 -0
- whatap/util/ip_util.py +63 -0
- whatap/util/keygen.py +11 -0
- whatap/util/linked_list.py +113 -0
- whatap/util/linked_map.py +359 -0
- whatap/util/metering_util.py +103 -0
- whatap/util/request_double_queue.py +68 -0
- whatap/util/request_queue.py +60 -0
- whatap/util/string_util.py +20 -0
- whatap/util/throttle_util.py +99 -0
- whatap/util/userid_util.py +134 -0
- whatap/value/__init__.py +1 -0
- whatap/value/blob_value.py +38 -0
- whatap/value/boolean_value.py +33 -0
- whatap/value/decimal_value.py +36 -0
- whatap/value/double_summary.py +86 -0
- whatap/value/double_value.py +33 -0
- whatap/value/float_array.py +42 -0
- whatap/value/float_value.py +34 -0
- whatap/value/int_array.py +42 -0
- whatap/value/ip4_value.py +50 -0
- whatap/value/list_value.py +105 -0
- whatap/value/long_array.py +44 -0
- whatap/value/long_summary.py +83 -0
- whatap/value/map_value.py +154 -0
- whatap/value/null_value.py +21 -0
- whatap/value/number_value.py +33 -0
- whatap/value/summary_value.py +39 -0
- whatap/value/text_array.py +58 -0
- whatap/value/text_hash_value.py +37 -0
- whatap/value/text_value.py +43 -0
- whatap/value/value.py +26 -0
- whatap/value/value_enum.py +80 -0
- whatap/whatap.conf +14 -0
- whatap_python-2.1.0.dist-info/METADATA +87 -0
- whatap_python-2.1.0.dist-info/RECORD +227 -0
- whatap_python-2.1.0.dist-info/WHEEL +5 -0
- whatap_python-2.1.0.dist-info/entry_points.txt +6 -0
- whatap_python-2.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
class LinkedList(object):
|
|
2
|
+
def __init__(self):
|
|
3
|
+
self._length = 0
|
|
4
|
+
self._head = None
|
|
5
|
+
self._current = None
|
|
6
|
+
self._tail = None
|
|
7
|
+
|
|
8
|
+
def size(self):
|
|
9
|
+
return self._length
|
|
10
|
+
|
|
11
|
+
def add(self, data):
|
|
12
|
+
node = {
|
|
13
|
+
'data': data,
|
|
14
|
+
'next': None,
|
|
15
|
+
'prev': None
|
|
16
|
+
}
|
|
17
|
+
if not self._head:
|
|
18
|
+
self._head = node
|
|
19
|
+
self._current = {'next': node}
|
|
20
|
+
else:
|
|
21
|
+
self._tail['next'] = node
|
|
22
|
+
node['prev'] = self._tail
|
|
23
|
+
|
|
24
|
+
self._tail = node
|
|
25
|
+
self._length += 1
|
|
26
|
+
|
|
27
|
+
def get(self, index):
|
|
28
|
+
if index > -1 and index < self._length:
|
|
29
|
+
current = self._head, i = 1
|
|
30
|
+
while i < index:
|
|
31
|
+
current = current['next']
|
|
32
|
+
i += 1
|
|
33
|
+
return current['data']
|
|
34
|
+
|
|
35
|
+
else:
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
def remove(self, index):
|
|
39
|
+
if index > -1 and index < self._length:
|
|
40
|
+
current = self._head, previous, i = 0
|
|
41
|
+
if index == 0:
|
|
42
|
+
self._head = current['next']
|
|
43
|
+
else:
|
|
44
|
+
i = 1
|
|
45
|
+
while i < index:
|
|
46
|
+
previous = current
|
|
47
|
+
current = current['next']
|
|
48
|
+
previous['next'] = current['next']
|
|
49
|
+
self._length -= 1
|
|
50
|
+
return current['data']
|
|
51
|
+
else:
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
def getFirst(self):
|
|
55
|
+
return self._head['data']
|
|
56
|
+
|
|
57
|
+
def getValue(self, ent):
|
|
58
|
+
if not ent:
|
|
59
|
+
return None
|
|
60
|
+
return ent['data']
|
|
61
|
+
|
|
62
|
+
def next(self):
|
|
63
|
+
if self._current['next']:
|
|
64
|
+
self._current = self._current['next']
|
|
65
|
+
return self._current['data']
|
|
66
|
+
else:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
def hasNext(self):
|
|
70
|
+
if self._current and self._current['next']:
|
|
71
|
+
return True
|
|
72
|
+
else:
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
def removeFirst(self):
|
|
76
|
+
target = self._head
|
|
77
|
+
if self._head:
|
|
78
|
+
if self._head == self._current['next']:
|
|
79
|
+
self._current = None
|
|
80
|
+
if self._head['next']:
|
|
81
|
+
self._head = self._head['next']
|
|
82
|
+
self._current = self._head
|
|
83
|
+
self._head['prev'] = None
|
|
84
|
+
else:
|
|
85
|
+
self._head = None
|
|
86
|
+
self._length -= 1
|
|
87
|
+
return target['data']
|
|
88
|
+
|
|
89
|
+
def removeEntry(self, current):
|
|
90
|
+
if not current:
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
if self._head == current:
|
|
94
|
+
self._head = current['next']
|
|
95
|
+
|
|
96
|
+
else:
|
|
97
|
+
previous = current
|
|
98
|
+
current = current['next']
|
|
99
|
+
previous['next'] = current['next']
|
|
100
|
+
self._length -= 1
|
|
101
|
+
|
|
102
|
+
# def toString(self):
|
|
103
|
+
# str = ''
|
|
104
|
+
# e = list.getFirst()
|
|
105
|
+
# if not e:
|
|
106
|
+
# return '[]'
|
|
107
|
+
# else:
|
|
108
|
+
# str = '[' + e['data']
|
|
109
|
+
# e = list.getNext(e)
|
|
110
|
+
# while e:
|
|
111
|
+
# str += ',' + e['data']
|
|
112
|
+
# e = list.getNext(e)
|
|
113
|
+
# return str + ']'
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
from whatap.util.hash_util import HashUtil
|
|
2
|
+
|
|
3
|
+
DEFAULT_CAPACITY = 101
|
|
4
|
+
DEFAULT_LOAD_FACTOR = 0.75
|
|
5
|
+
TYPE = {
|
|
6
|
+
'KEYS': 0,
|
|
7
|
+
'VALUES': 1,
|
|
8
|
+
'ENTRIES': 2
|
|
9
|
+
}
|
|
10
|
+
MODE = {
|
|
11
|
+
'FORCE_FIRST': 0,
|
|
12
|
+
'FORCE_LAST': 1,
|
|
13
|
+
'FIRST': 2,
|
|
14
|
+
'LAST': 3
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LinkedEntry(object):
|
|
19
|
+
def __init__(self, key, value, next):
|
|
20
|
+
self.key = key
|
|
21
|
+
self.value = value
|
|
22
|
+
self.next = next
|
|
23
|
+
self.link_next = None
|
|
24
|
+
self.link_prev = None
|
|
25
|
+
|
|
26
|
+
def getKey(self):
|
|
27
|
+
return self.key
|
|
28
|
+
|
|
29
|
+
def getValue(self):
|
|
30
|
+
return self.value
|
|
31
|
+
|
|
32
|
+
def setValue(self, value):
|
|
33
|
+
oldValue = self.value
|
|
34
|
+
self.value = value
|
|
35
|
+
return oldValue
|
|
36
|
+
|
|
37
|
+
def hashCode(self):
|
|
38
|
+
return HashUtil.hashFromString(self.key)
|
|
39
|
+
|
|
40
|
+
def toString(self):
|
|
41
|
+
return self.key + "=" + self.value
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Enumer():
|
|
45
|
+
def __init__(self, map, type):
|
|
46
|
+
self.map = map
|
|
47
|
+
self.entry = map.header.link_next
|
|
48
|
+
self.lastEnt = None
|
|
49
|
+
self.type = type if type else TYPE['ENTRIES']
|
|
50
|
+
|
|
51
|
+
def hasMoreElements(self):
|
|
52
|
+
return self.map.header is not self.entry and self.entry is not None
|
|
53
|
+
|
|
54
|
+
def nextElement(self):
|
|
55
|
+
if self.hasMoreElements():
|
|
56
|
+
e = self.lastEnt = self.entry
|
|
57
|
+
self.entry = e.link_next
|
|
58
|
+
if self.type == TYPE['KEYS']:
|
|
59
|
+
return e.key
|
|
60
|
+
elif self.type == TYPE['VALUES']:
|
|
61
|
+
return e.value
|
|
62
|
+
else:
|
|
63
|
+
return e
|
|
64
|
+
else:
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class LinkedMap(object):
|
|
69
|
+
MODE = MODE
|
|
70
|
+
|
|
71
|
+
def __init__(self, initCapacity=None, loadFactor=None):
|
|
72
|
+
self.initCapacity = initCapacity if initCapacity else DEFAULT_CAPACITY
|
|
73
|
+
self.loadFactor = loadFactor if loadFactor else DEFAULT_LOAD_FACTOR
|
|
74
|
+
self.threshold = int(self.initCapacity * self.loadFactor)
|
|
75
|
+
|
|
76
|
+
self.table = [None for _ in range(self.initCapacity)]
|
|
77
|
+
self.header = LinkedEntry(None, None, None)
|
|
78
|
+
self.header.link_next = self.header.link_prev = self.header
|
|
79
|
+
self.count = 0
|
|
80
|
+
self.max = 0
|
|
81
|
+
|
|
82
|
+
def size(self):
|
|
83
|
+
return self.count
|
|
84
|
+
|
|
85
|
+
def keys(self):
|
|
86
|
+
return Enumer(self, TYPE['KEYS'])
|
|
87
|
+
|
|
88
|
+
def values(self):
|
|
89
|
+
return Enumer(self, TYPE['VALUES'])
|
|
90
|
+
|
|
91
|
+
def entries(self):
|
|
92
|
+
return Enumer(self, TYPE['ENTRIES'])
|
|
93
|
+
|
|
94
|
+
def containsKey(self, key):
|
|
95
|
+
if key is None:
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
tab = self.table
|
|
99
|
+
index = self.hash(key) % len(tab)
|
|
100
|
+
e = tab[index]
|
|
101
|
+
|
|
102
|
+
while True:
|
|
103
|
+
if not e:
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
if e.key == key:
|
|
107
|
+
return True
|
|
108
|
+
e = e.next
|
|
109
|
+
|
|
110
|
+
def get(self, key):
|
|
111
|
+
if key is None:
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
tab = self.table
|
|
115
|
+
index = self.hash(key) % len(tab)
|
|
116
|
+
e = tab[index]
|
|
117
|
+
|
|
118
|
+
while True:
|
|
119
|
+
if not e:
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
if e.key == key:
|
|
123
|
+
return e.value
|
|
124
|
+
e = e.next
|
|
125
|
+
|
|
126
|
+
def getLastValue(self):
|
|
127
|
+
if self.isEmpty():
|
|
128
|
+
return None
|
|
129
|
+
return self.header.link_prev.value
|
|
130
|
+
|
|
131
|
+
def hash(self, key):
|
|
132
|
+
if not key:
|
|
133
|
+
return 0
|
|
134
|
+
return HashUtil.hashFromString(str(key)) & 0x7fffffff
|
|
135
|
+
|
|
136
|
+
def rehash(self):
|
|
137
|
+
oldCapacity = len(self.table)
|
|
138
|
+
oldMap = self.table
|
|
139
|
+
newCapacity = oldCapacity * 2 + 1
|
|
140
|
+
newMap = [None for _ in range(newCapacity)]
|
|
141
|
+
self.threshold = int(newCapacity * self.loadFactor)
|
|
142
|
+
self.table = newMap
|
|
143
|
+
|
|
144
|
+
for i in range(oldCapacity -1, -1, -1):
|
|
145
|
+
old = oldMap[i]
|
|
146
|
+
while True:
|
|
147
|
+
if not old:
|
|
148
|
+
break
|
|
149
|
+
|
|
150
|
+
e = old
|
|
151
|
+
old = old.next
|
|
152
|
+
key = e.key
|
|
153
|
+
index = self.hash(key) % newCapacity
|
|
154
|
+
e.next = newMap[index]
|
|
155
|
+
newMap[index] = e
|
|
156
|
+
|
|
157
|
+
def isEmpty(self):
|
|
158
|
+
return self.size() == 0
|
|
159
|
+
|
|
160
|
+
def setMax(self, max):
|
|
161
|
+
self.max = max
|
|
162
|
+
return self
|
|
163
|
+
|
|
164
|
+
def isFull(self):
|
|
165
|
+
return self.max > 0 and self.max <= self.count
|
|
166
|
+
|
|
167
|
+
def put(self, key, value):
|
|
168
|
+
return self._put(key, value, MODE['LAST'])
|
|
169
|
+
|
|
170
|
+
def putLast(self, key, value):
|
|
171
|
+
return self._put(key, value, MODE['FORCE_LAST'])
|
|
172
|
+
|
|
173
|
+
def putFirst(self, key, value):
|
|
174
|
+
return self._put(key, value, MODE['FORCE_FIRST'])
|
|
175
|
+
|
|
176
|
+
def _put(self, key, value, m, noover=False):
|
|
177
|
+
if noover and self.max > 0 and self.size() > self.max:
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
tab = self.table
|
|
181
|
+
index = self.hash(key) % len(tab)
|
|
182
|
+
e = tab[index]
|
|
183
|
+
|
|
184
|
+
while True:
|
|
185
|
+
if not e:
|
|
186
|
+
break
|
|
187
|
+
|
|
188
|
+
if e.key == key:
|
|
189
|
+
old = e.value
|
|
190
|
+
e.value = value
|
|
191
|
+
if m == MODE['FORCE_FIRST']:
|
|
192
|
+
if self.header.link_next != e:
|
|
193
|
+
self.unchain(e)
|
|
194
|
+
self.chain(self.header, self.header.link_next, e)
|
|
195
|
+
elif m == MODE['FORCE_LAST']:
|
|
196
|
+
if self.header.link_prev != e:
|
|
197
|
+
self.unchain(e)
|
|
198
|
+
self.chain(self.header.link_prev, self.header, e)
|
|
199
|
+
return old
|
|
200
|
+
|
|
201
|
+
e = e.next
|
|
202
|
+
|
|
203
|
+
if self.max > 0:
|
|
204
|
+
if m == MODE['FORCE_FIRST'] or m == MODE['FIRST']:
|
|
205
|
+
while self.count >= self.max:
|
|
206
|
+
k = self.header.link_prev.key
|
|
207
|
+
v = self.remove(k)
|
|
208
|
+
self.overflowed(k, v)
|
|
209
|
+
elif m == MODE['FORCE_LAST'] or m == MODE['LAST']:
|
|
210
|
+
while self.count >= self.max:
|
|
211
|
+
k = self.header.link_next.key
|
|
212
|
+
v = self.remove(k)
|
|
213
|
+
self.overflowed(k, v)
|
|
214
|
+
|
|
215
|
+
if self.count >= self.threshold:
|
|
216
|
+
self.rehash()
|
|
217
|
+
tab = self.table
|
|
218
|
+
index = self.hash(key) % len(tab)
|
|
219
|
+
|
|
220
|
+
e = LinkedEntry(key, value, tab[index])
|
|
221
|
+
tab[index] = e
|
|
222
|
+
|
|
223
|
+
if m == MODE['FORCE_FIRST'] or m == MODE['FIRST']:
|
|
224
|
+
self.chain(self.header, self.header.link_next, e)
|
|
225
|
+
elif m == MODE['FORCE_LAST'] or m == MODE['LAST']:
|
|
226
|
+
self.chain(self.header.link_prev, self.header, e)
|
|
227
|
+
|
|
228
|
+
self.count += 1
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
def overflowed(self, key, value):
|
|
232
|
+
return
|
|
233
|
+
|
|
234
|
+
def create(self, key):
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
def intern(self, key):
|
|
238
|
+
return self._intern(key, MODE['LAST'])
|
|
239
|
+
|
|
240
|
+
def _intern(self, key, m):
|
|
241
|
+
tab = self.table
|
|
242
|
+
index = self.hash(key) % len(tab)
|
|
243
|
+
e = tab[index]
|
|
244
|
+
|
|
245
|
+
while True:
|
|
246
|
+
if not e:
|
|
247
|
+
break
|
|
248
|
+
|
|
249
|
+
if e.key == key:
|
|
250
|
+
old = e.value
|
|
251
|
+
|
|
252
|
+
if m == MODE['FORCE_FIRST']:
|
|
253
|
+
if self.header.link_next != e:
|
|
254
|
+
self.unchain(e)
|
|
255
|
+
self.chain(self.header, self.header.link_next, e)
|
|
256
|
+
elif m == MODE['FORCE_LAST']:
|
|
257
|
+
if self.header.link_prev != e:
|
|
258
|
+
self.unchain(e)
|
|
259
|
+
self.chain(self.header.link_prev, self.header, e)
|
|
260
|
+
return old
|
|
261
|
+
e = e.next
|
|
262
|
+
|
|
263
|
+
value = self.create(self, key)
|
|
264
|
+
if not value:
|
|
265
|
+
return None
|
|
266
|
+
|
|
267
|
+
if self.max > 0:
|
|
268
|
+
if m == MODE['FORCE_FIRST'] or m == MODE['FIRST']:
|
|
269
|
+
while self.count >= self.max:
|
|
270
|
+
k = self.header.link_prev.key
|
|
271
|
+
v = self.remove(k)
|
|
272
|
+
self.overflowed(k, v)
|
|
273
|
+
elif m == MODE['FORCE_LAST'] or m == MODE['LAST']:
|
|
274
|
+
while self.count >= self.max:
|
|
275
|
+
k = self.header.link_next.key
|
|
276
|
+
v = self.remove(k)
|
|
277
|
+
self.overflowed(k, v)
|
|
278
|
+
|
|
279
|
+
if self.count >= self.threshold:
|
|
280
|
+
self.rehash()
|
|
281
|
+
tab = self.table
|
|
282
|
+
index = self.hash(key) % len(tab)
|
|
283
|
+
|
|
284
|
+
e = LinkedEntry(key, value, tab[index])
|
|
285
|
+
tab[index] = e
|
|
286
|
+
|
|
287
|
+
if m == MODE['FORCE_FIRST'] or m == MODE['FIRST']:
|
|
288
|
+
self.chain(self.header, self.header.link_next, e)
|
|
289
|
+
elif m == MODE['FORCE_LAST'] or m == MODE['LAST']:
|
|
290
|
+
self.chain(self.header.link_prev, self.header, e)
|
|
291
|
+
|
|
292
|
+
self.count += 1
|
|
293
|
+
return value
|
|
294
|
+
|
|
295
|
+
def remove(self, key):
|
|
296
|
+
if key is None:
|
|
297
|
+
return None
|
|
298
|
+
|
|
299
|
+
tab = self.table
|
|
300
|
+
index = self.hash(key) % len(tab)
|
|
301
|
+
e = tab[index]
|
|
302
|
+
prev = None
|
|
303
|
+
|
|
304
|
+
while True:
|
|
305
|
+
if not e:
|
|
306
|
+
return None
|
|
307
|
+
|
|
308
|
+
if e.key == key:
|
|
309
|
+
if prev:
|
|
310
|
+
prev.next = e.next
|
|
311
|
+
else:
|
|
312
|
+
tab[index] = e.next
|
|
313
|
+
|
|
314
|
+
self.count -= 1
|
|
315
|
+
oldValue = e.value
|
|
316
|
+
e.value = None
|
|
317
|
+
self.unchain(e)
|
|
318
|
+
return oldValue
|
|
319
|
+
|
|
320
|
+
prev = e
|
|
321
|
+
e = e.next
|
|
322
|
+
return None
|
|
323
|
+
|
|
324
|
+
def removeFirst(self):
|
|
325
|
+
if self.isEmpty():
|
|
326
|
+
return None
|
|
327
|
+
return self.remove(self.header.link_next.key)
|
|
328
|
+
|
|
329
|
+
def removeLast(self):
|
|
330
|
+
if self.isEmpty():
|
|
331
|
+
return None
|
|
332
|
+
return self.remove(self.header.link_prev.key)
|
|
333
|
+
|
|
334
|
+
def clear(self):
|
|
335
|
+
tab = self.table
|
|
336
|
+
for i, t in enumerate(tab):
|
|
337
|
+
tab[i] = None
|
|
338
|
+
self.header.link_next = self.header.link_prev = self.header
|
|
339
|
+
self.count = 0
|
|
340
|
+
|
|
341
|
+
def chain(self, link_prev, link_next, e):
|
|
342
|
+
e.link_prev = link_prev
|
|
343
|
+
e.link_next = link_next
|
|
344
|
+
link_prev.link_next = e
|
|
345
|
+
link_next.link_prev = e
|
|
346
|
+
|
|
347
|
+
def unchain(self, e):
|
|
348
|
+
e.link_prev.link_next = e.link_next
|
|
349
|
+
e.link_next.link_prev = e.link_prev
|
|
350
|
+
e.link_prev = None
|
|
351
|
+
e.link_next = None
|
|
352
|
+
|
|
353
|
+
def putAll(self, other):
|
|
354
|
+
if not other or not isinstance(other, LinkedMap):
|
|
355
|
+
return
|
|
356
|
+
it = other.entries()
|
|
357
|
+
while it.hasMoreElements():
|
|
358
|
+
e = it.nextElement()
|
|
359
|
+
self.put(e.getKey(), e.getValue())
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from whatap.util.date_util import DateUtil
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class MeteringUtil(object):
|
|
5
|
+
def MeteringUtil(self, timeUnit=1000, bucketSize=301,
|
|
6
|
+
create=None, clear=None):
|
|
7
|
+
self.TIME_UNIT = timeUnit
|
|
8
|
+
self.BUCKET_SIZE = bucketSize
|
|
9
|
+
self._time_ = self.getTime()
|
|
10
|
+
self._pos_ = self._time_ % self.BUCKET_SIZE
|
|
11
|
+
self.table = [self.create() for _ in range(bucketSize)]
|
|
12
|
+
|
|
13
|
+
self.create = create
|
|
14
|
+
self.clear = clear
|
|
15
|
+
|
|
16
|
+
def create(self):
|
|
17
|
+
return self.create
|
|
18
|
+
|
|
19
|
+
def clear(self):
|
|
20
|
+
return self.clear
|
|
21
|
+
|
|
22
|
+
def getLastBucket(self):
|
|
23
|
+
pos = self.getPosition()
|
|
24
|
+
return self.table[self.stepback(pos)]
|
|
25
|
+
|
|
26
|
+
def getLastTwoBucket(self):
|
|
27
|
+
pos = self.stepback(self.getPosition())
|
|
28
|
+
t1 = self.table[pos]
|
|
29
|
+
pos = self.stepback(pos)
|
|
30
|
+
t2 = self.table[pos]
|
|
31
|
+
if not t1:
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
return [t1, t2]
|
|
35
|
+
|
|
36
|
+
def getCurrentBucket(self, time=None):
|
|
37
|
+
if not time:
|
|
38
|
+
pos = self.getPosition()
|
|
39
|
+
return self.table[pos]
|
|
40
|
+
else:
|
|
41
|
+
pos = self.getPosition(time)
|
|
42
|
+
if pos >= 0:
|
|
43
|
+
return self.table[pos]
|
|
44
|
+
else:
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
def getPosition(self, time=None):
|
|
48
|
+
curTime = self.getTime()
|
|
49
|
+
if curTime != self._time_:
|
|
50
|
+
i = 0
|
|
51
|
+
while (curTime - self._time_) and i < self.BUCKET_SIZE:
|
|
52
|
+
_pos_ = 0 if self._pos_ + 1 > self.BUCKET_SIZE - 1 \
|
|
53
|
+
else self._pos_ + 1
|
|
54
|
+
self.clear(self.table[_pos_])
|
|
55
|
+
i += 1
|
|
56
|
+
|
|
57
|
+
self._time_ = curTime
|
|
58
|
+
self._pos_ = int(self._time_ % self.BUCKET_SIZE)
|
|
59
|
+
|
|
60
|
+
if not time:
|
|
61
|
+
return self._pos_
|
|
62
|
+
else:
|
|
63
|
+
theTime = time / self.TIME_UNIT
|
|
64
|
+
if theTime > curTime or theTime < curTime - self.BUCKET_SIZE + 2:
|
|
65
|
+
return -1
|
|
66
|
+
return int(theTime % self.BUCKET_SIZE)
|
|
67
|
+
|
|
68
|
+
def check(self, period):
|
|
69
|
+
if period >= self.BUCKET_SIZE:
|
|
70
|
+
period = self.BUCKET_SIZE - 1
|
|
71
|
+
return period
|
|
72
|
+
|
|
73
|
+
def stepback(self, pos):
|
|
74
|
+
if not pos:
|
|
75
|
+
pos = self.BUCKET_SIZE - 1
|
|
76
|
+
else:
|
|
77
|
+
pos -= 1
|
|
78
|
+
return pos
|
|
79
|
+
|
|
80
|
+
def search(self, period, h=None, skip=None):
|
|
81
|
+
period = self.check(period)
|
|
82
|
+
pos = self.getPosition()
|
|
83
|
+
|
|
84
|
+
if not h and not skip:
|
|
85
|
+
out = []
|
|
86
|
+
for i in range(period):
|
|
87
|
+
out.append(self.table[pos])
|
|
88
|
+
return out
|
|
89
|
+
else:
|
|
90
|
+
if skip:
|
|
91
|
+
for _ in skip:
|
|
92
|
+
pos = self.stepback(pos)
|
|
93
|
+
|
|
94
|
+
i = 0
|
|
95
|
+
while i < period:
|
|
96
|
+
h.process(self.table[pos])
|
|
97
|
+
pos = self.stepback(pos)
|
|
98
|
+
i += 1
|
|
99
|
+
|
|
100
|
+
return period
|
|
101
|
+
|
|
102
|
+
def getTime(self):
|
|
103
|
+
return DateUtil.currentTime() / self.TIME_UNIT
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from whatap import logging
|
|
4
|
+
from whatap.util.linked_list import LinkedList
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RequestDoubleQueue(object):
|
|
8
|
+
def __init__(self, capacity1, capacity2):
|
|
9
|
+
self.capacity1 = capacity1
|
|
10
|
+
self.capacity2 = capacity2
|
|
11
|
+
self.queue1 = LinkedList()
|
|
12
|
+
self.queue2 = LinkedList()
|
|
13
|
+
|
|
14
|
+
def get(self):
|
|
15
|
+
while self.queue1.size() <= 0 and self.queue2.size() <= 0:
|
|
16
|
+
try:
|
|
17
|
+
time.sleep(0.5)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
logging.debug(e, extra={'id': 'WA510'}, exc_info=True)
|
|
20
|
+
|
|
21
|
+
if self.queue1.size() > 0:
|
|
22
|
+
return self.queue1.removeFirst()
|
|
23
|
+
elif self.queue2.size() > 0:
|
|
24
|
+
return self.queue2.removeFirst()
|
|
25
|
+
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
def hasNext(self):
|
|
29
|
+
if self.queue1.hasNext() or self.queue2.hasNext():
|
|
30
|
+
return True
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
def putForce1(self, o):
|
|
34
|
+
return self.putForce(self.queue1, self.capacity1, o)
|
|
35
|
+
|
|
36
|
+
def putForce2(self, o):
|
|
37
|
+
return self.putForce(self.queue2, self.capacity2, o)
|
|
38
|
+
|
|
39
|
+
def putForce(self, q, sz, o):
|
|
40
|
+
if sz <= 0 or q.size() < self.capacity1:
|
|
41
|
+
q.add(o)
|
|
42
|
+
return True
|
|
43
|
+
else:
|
|
44
|
+
while q.size() >= sz:
|
|
45
|
+
v = q.removeFirst()
|
|
46
|
+
self.overflowed(v)
|
|
47
|
+
q.add(o)
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def put1(self, o):
|
|
51
|
+
return self.put(self.queue1, self.capacity1, o)
|
|
52
|
+
|
|
53
|
+
def put2(self, o):
|
|
54
|
+
return self.put(self.queue1, self.capacity2, o)
|
|
55
|
+
|
|
56
|
+
def put(self, queue, capacity, o):
|
|
57
|
+
if capacity <= 0 or queue.size() < capacity:
|
|
58
|
+
queue.add(o)
|
|
59
|
+
return True
|
|
60
|
+
else:
|
|
61
|
+
self.failed(o)
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
def failed(self, v):
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
def overflowed(self, v):
|
|
68
|
+
return
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from whatap import logging
|
|
4
|
+
from whatap.util.date_util import DateUtil
|
|
5
|
+
from whatap.util.linked_list import LinkedList
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RequestQueue(object):
|
|
9
|
+
def __init__(self, capacity):
|
|
10
|
+
self.capacity = capacity
|
|
11
|
+
self.queue = LinkedList()
|
|
12
|
+
|
|
13
|
+
def get(self, timeout=None):
|
|
14
|
+
if not timeout:
|
|
15
|
+
while self.queue.size() <= 0:
|
|
16
|
+
try:
|
|
17
|
+
time.sleep(0.5)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
logging.debug(e, extra={'id': 'WA520'}, exc_info=True)
|
|
20
|
+
return self.queue.removeFirst()
|
|
21
|
+
else:
|
|
22
|
+
if self.queue.size() > 0:
|
|
23
|
+
return self.queue.removeFirst()
|
|
24
|
+
|
|
25
|
+
timeto = DateUtil.currentTime() + timeout
|
|
26
|
+
while not self.queue.size():
|
|
27
|
+
try:
|
|
28
|
+
if timeout > 0:
|
|
29
|
+
time.sleep(5)
|
|
30
|
+
|
|
31
|
+
except Exception as e:
|
|
32
|
+
logging.debug(e, extra={'id': 'WA521'}, exc_info=True)
|
|
33
|
+
|
|
34
|
+
if timeto - DateUtil.currentTime() <= 0:
|
|
35
|
+
break
|
|
36
|
+
|
|
37
|
+
if self.queue.size() > 0:
|
|
38
|
+
return self.queue.removeFirst()
|
|
39
|
+
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
def put(self, o):
|
|
43
|
+
if self.capacity <= 0 or self.queue.size() < self.capacity:
|
|
44
|
+
self.queue.add(o)
|
|
45
|
+
return True
|
|
46
|
+
else:
|
|
47
|
+
self.failed(o)
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def size(self):
|
|
51
|
+
return self.queue.size()
|
|
52
|
+
|
|
53
|
+
def clear(self):
|
|
54
|
+
self.queue = LinkedList()
|
|
55
|
+
|
|
56
|
+
def failed(self, v):
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
def overflowed(self, v):
|
|
60
|
+
return
|