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.
Files changed (227) hide show
  1. whatap/LICENSE +0 -0
  2. whatap/README.rst +49 -0
  3. whatap/__init__.py +923 -0
  4. whatap/__main__.py +4 -0
  5. whatap/agent/darwin/amd64/whatap_python +0 -0
  6. whatap/agent/darwin/arm64/whatap_python +0 -0
  7. whatap/agent/linux/amd64/whatap_python +0 -0
  8. whatap/agent/linux/arm64/whatap_python +0 -0
  9. whatap/agent/windows/whatap_python.exe +0 -0
  10. whatap/bootstrap/__init__.py +0 -0
  11. whatap/bootstrap/sitecustomize.py +19 -0
  12. whatap/build.py +4 -0
  13. whatap/conf/__init__.py +0 -0
  14. whatap/conf/configuration.py +280 -0
  15. whatap/conf/configure.py +105 -0
  16. whatap/conf/license.py +49 -0
  17. whatap/control/__init__.py +0 -0
  18. whatap/counter/__init__.py +14 -0
  19. whatap/counter/counter_manager.py +45 -0
  20. whatap/counter/tasks/__init__.py +3 -0
  21. whatap/counter/tasks/base_task.py +26 -0
  22. whatap/counter/tasks/llm_evaluator_task.py +501 -0
  23. whatap/counter/tasks/llm_log_sink_task.py +309 -0
  24. whatap/counter/tasks/llm_stat_task.py +78 -0
  25. whatap/counter/tasks/openfiledescriptor.py +67 -0
  26. whatap/io/__init__.py +1 -0
  27. whatap/io/data_inputx.py +161 -0
  28. whatap/io/data_outputx.py +262 -0
  29. whatap/llm/__init__.py +17 -0
  30. whatap/llm/definitions.py +43 -0
  31. whatap/llm/evaluators/__init__.py +136 -0
  32. whatap/llm/evaluators/base.py +114 -0
  33. whatap/llm/evaluators/builtins/__init__.py +91 -0
  34. whatap/llm/evaluators/builtins/answer_relevance.py +46 -0
  35. whatap/llm/evaluators/builtins/combined_judge.py +271 -0
  36. whatap/llm/evaluators/builtins/factuality.py +71 -0
  37. whatap/llm/evaluators/builtins/hallucination.py +97 -0
  38. whatap/llm/evaluators/builtins/llm_judge.py +516 -0
  39. whatap/llm/evaluators/builtins/pii_leak.py +214 -0
  40. whatap/llm/evaluators/builtins/prompt_injection.py +71 -0
  41. whatap/llm/evaluators/builtins/toxicity.py +53 -0
  42. whatap/llm/evaluators/builtins/url_scan.py +194 -0
  43. whatap/llm/evaluators/registry.py +192 -0
  44. whatap/llm/evaluators/sampler.py +83 -0
  45. whatap/llm/evaluators/scope.py +334 -0
  46. whatap/llm/features.py +66 -0
  47. whatap/llm/log_sink_packs/__init__.py +9 -0
  48. whatap/llm/log_sink_packs/llm_input_message.py +16 -0
  49. whatap/llm/log_sink_packs/llm_log_sink_pack.py +72 -0
  50. whatap/llm/log_sink_packs/llm_output_message.py +19 -0
  51. whatap/llm/log_sink_packs/llm_step_eval_status.py +94 -0
  52. whatap/llm/log_sink_packs/llm_step_status.py +118 -0
  53. whatap/llm/log_sink_packs/llm_system_message.py +16 -0
  54. whatap/llm/log_sink_packs/llm_tool_calls.py +44 -0
  55. whatap/llm/log_sink_packs/llm_tool_results.py +16 -0
  56. whatap/llm/log_sink_packs/llm_tx_status.py +108 -0
  57. whatap/llm/pricing.py +236 -0
  58. whatap/llm/prompt_meta.py +288 -0
  59. whatap/llm/providers/__init__.py +0 -0
  60. whatap/llm/providers/anthropic/__init__.py +37 -0
  61. whatap/llm/providers/anthropic/messages/__init__.py +0 -0
  62. whatap/llm/providers/anthropic/messages/messages.py +70 -0
  63. whatap/llm/providers/anthropic/messages/messages_context.py +76 -0
  64. whatap/llm/providers/anthropic/messages/messages_extractor.py +126 -0
  65. whatap/llm/providers/interceptor.py +182 -0
  66. whatap/llm/providers/openai/__init__.py +133 -0
  67. whatap/llm/providers/openai/chat/__init__.py +0 -0
  68. whatap/llm/providers/openai/chat/chat.py +82 -0
  69. whatap/llm/providers/openai/chat/chat_context.py +78 -0
  70. whatap/llm/providers/openai/chat/chat_extractor.py +127 -0
  71. whatap/llm/providers/openai/completions/__init__.py +0 -0
  72. whatap/llm/providers/openai/completions/completions.py +70 -0
  73. whatap/llm/providers/openai/completions/completions_context.py +31 -0
  74. whatap/llm/providers/openai/completions/completions_extractor.py +61 -0
  75. whatap/llm/providers/openai/content_parser.py +41 -0
  76. whatap/llm/providers/openai/embeddings/__init__.py +0 -0
  77. whatap/llm/providers/openai/embeddings/embeddings.py +59 -0
  78. whatap/llm/providers/openai/embeddings/embeddings_context.py +25 -0
  79. whatap/llm/providers/openai/embeddings/embeddings_extractor.py +26 -0
  80. whatap/llm/providers/openai/responses/__init__.py +0 -0
  81. whatap/llm/providers/openai/responses/responses.py +70 -0
  82. whatap/llm/providers/openai/responses/responses_context.py +88 -0
  83. whatap/llm/providers/openai/responses/responses_extractor.py +126 -0
  84. whatap/llm/providers/stream_accumulator.py +73 -0
  85. whatap/llm/stats/__init__.py +35 -0
  86. whatap/llm/stats/active_stat.py +86 -0
  87. whatap/llm/stats/answer_relevance_eval_stat.py +10 -0
  88. whatap/llm/stats/api_status_stat.py +35 -0
  89. whatap/llm/stats/base_stat.py +107 -0
  90. whatap/llm/stats/combined_judge_eval_stat.py +11 -0
  91. whatap/llm/stats/error_stat.py +59 -0
  92. whatap/llm/stats/eval_stat.py +225 -0
  93. whatap/llm/stats/factuality_eval_stat.py +10 -0
  94. whatap/llm/stats/feature_stat.py +104 -0
  95. whatap/llm/stats/finish_stat.py +105 -0
  96. whatap/llm/stats/hallucination_eval_stat.py +10 -0
  97. whatap/llm/stats/meter.py +18 -0
  98. whatap/llm/stats/perf_stat.py +117 -0
  99. whatap/llm/stats/pii_leak_eval_stat.py +12 -0
  100. whatap/llm/stats/prompt_injection_eval_stat.py +10 -0
  101. whatap/llm/stats/token_usage_stat.py +133 -0
  102. whatap/llm/stats/toxicity_eval_stat.py +10 -0
  103. whatap/llm/stats/url_scan_eval_stat.py +12 -0
  104. whatap/net/__init__.py +0 -0
  105. whatap/net/async_sender.py +107 -0
  106. whatap/net/packet_enum.py +44 -0
  107. whatap/net/packet_type_enum.py +31 -0
  108. whatap/net/param_def.py +69 -0
  109. whatap/net/stackhelper.py +87 -0
  110. whatap/net/udp_session.py +394 -0
  111. whatap/net/udp_thread.py +54 -0
  112. whatap/pack/__init__.py +0 -0
  113. whatap/pack/logSinkPack.py +77 -0
  114. whatap/pack/pack.py +34 -0
  115. whatap/pack/pack_enum.py +41 -0
  116. whatap/pack/tagCountPack.py +61 -0
  117. whatap/scripts/__init__.py +208 -0
  118. whatap/trace/__init__.py +12 -0
  119. whatap/trace/mod/__init__.py +0 -0
  120. whatap/trace/mod/amqp/__init__.py +0 -0
  121. whatap/trace/mod/amqp/kombu.py +122 -0
  122. whatap/trace/mod/amqp/pika.py +62 -0
  123. whatap/trace/mod/application/__init__.py +0 -0
  124. whatap/trace/mod/application/bottle.py +34 -0
  125. whatap/trace/mod/application/celery.py +81 -0
  126. whatap/trace/mod/application/cherrypy.py +30 -0
  127. whatap/trace/mod/application/django.py +287 -0
  128. whatap/trace/mod/application/django_asgi.py +266 -0
  129. whatap/trace/mod/application/django_py3.py +251 -0
  130. whatap/trace/mod/application/fastapi/__init__.py +31 -0
  131. whatap/trace/mod/application/fastapi/endpoint.py +73 -0
  132. whatap/trace/mod/application/fastapi/exception_log.py +63 -0
  133. whatap/trace/mod/application/fastapi/instrumentation.py +204 -0
  134. whatap/trace/mod/application/fastapi/scope.py +115 -0
  135. whatap/trace/mod/application/fastapi/transaction.py +67 -0
  136. whatap/trace/mod/application/flask.py +52 -0
  137. whatap/trace/mod/application/frappe.py +224 -0
  138. whatap/trace/mod/application/graphql.py +170 -0
  139. whatap/trace/mod/application/nameko.py +39 -0
  140. whatap/trace/mod/application/odoo.py +63 -0
  141. whatap/trace/mod/application/starlette.py +126 -0
  142. whatap/trace/mod/application/tornado.py +163 -0
  143. whatap/trace/mod/application/wsgi.py +195 -0
  144. whatap/trace/mod/database/__init__.py +0 -0
  145. whatap/trace/mod/database/cxoracle.py +49 -0
  146. whatap/trace/mod/database/mongo.py +169 -0
  147. whatap/trace/mod/database/mysql.py +80 -0
  148. whatap/trace/mod/database/neo4j.py +90 -0
  149. whatap/trace/mod/database/psycopg2.py +45 -0
  150. whatap/trace/mod/database/psycopg3.py +359 -0
  151. whatap/trace/mod/database/redis.py +122 -0
  152. whatap/trace/mod/database/sqlalchemy.py +213 -0
  153. whatap/trace/mod/database/sqlite3.py +130 -0
  154. whatap/trace/mod/database/util.py +630 -0
  155. whatap/trace/mod/email/__init__.py +0 -0
  156. whatap/trace/mod/email/smtp.py +78 -0
  157. whatap/trace/mod/httpc/__init__.py +0 -0
  158. whatap/trace/mod/httpc/django.py +31 -0
  159. whatap/trace/mod/httpc/httplib.py +70 -0
  160. whatap/trace/mod/httpc/httpx.py +62 -0
  161. whatap/trace/mod/httpc/requests.py +20 -0
  162. whatap/trace/mod/httpc/urllib3.py +27 -0
  163. whatap/trace/mod/httpc/util.py +388 -0
  164. whatap/trace/mod/logging.py +161 -0
  165. whatap/trace/mod/plugin.py +84 -0
  166. whatap/trace/mod/standalone/__init__.py +0 -0
  167. whatap/trace/mod/standalone/multiple.py +293 -0
  168. whatap/trace/mod/standalone/single.py +135 -0
  169. whatap/trace/simple_trace_context.py +18 -0
  170. whatap/trace/trace_context.py +212 -0
  171. whatap/trace/trace_context_manager.py +244 -0
  172. whatap/trace/trace_error.py +84 -0
  173. whatap/trace/trace_handler.py +89 -0
  174. whatap/trace/trace_import.py +91 -0
  175. whatap/trace/trace_module_definition.py +156 -0
  176. whatap/util/__init__.py +0 -0
  177. whatap/util/bit_util.py +49 -0
  178. whatap/util/cardinality/__init__.py +0 -0
  179. whatap/util/cardinality/hyperloglog.py +84 -0
  180. whatap/util/cardinality/murmurhash.py +20 -0
  181. whatap/util/cardinality/registerset.py +60 -0
  182. whatap/util/compare_util.py +19 -0
  183. whatap/util/date_util.py +55 -0
  184. whatap/util/debug_util.py +73 -0
  185. whatap/util/escape_literal_sql.py +233 -0
  186. whatap/util/frame_util.py +20 -0
  187. whatap/util/hash_util.py +103 -0
  188. whatap/util/hexa32.py +66 -0
  189. whatap/util/int_set.py +199 -0
  190. whatap/util/ip_util.py +63 -0
  191. whatap/util/keygen.py +11 -0
  192. whatap/util/linked_list.py +113 -0
  193. whatap/util/linked_map.py +359 -0
  194. whatap/util/metering_util.py +103 -0
  195. whatap/util/request_double_queue.py +68 -0
  196. whatap/util/request_queue.py +60 -0
  197. whatap/util/string_util.py +20 -0
  198. whatap/util/throttle_util.py +99 -0
  199. whatap/util/userid_util.py +134 -0
  200. whatap/value/__init__.py +1 -0
  201. whatap/value/blob_value.py +38 -0
  202. whatap/value/boolean_value.py +33 -0
  203. whatap/value/decimal_value.py +36 -0
  204. whatap/value/double_summary.py +86 -0
  205. whatap/value/double_value.py +33 -0
  206. whatap/value/float_array.py +42 -0
  207. whatap/value/float_value.py +34 -0
  208. whatap/value/int_array.py +42 -0
  209. whatap/value/ip4_value.py +50 -0
  210. whatap/value/list_value.py +105 -0
  211. whatap/value/long_array.py +44 -0
  212. whatap/value/long_summary.py +83 -0
  213. whatap/value/map_value.py +154 -0
  214. whatap/value/null_value.py +21 -0
  215. whatap/value/number_value.py +33 -0
  216. whatap/value/summary_value.py +39 -0
  217. whatap/value/text_array.py +58 -0
  218. whatap/value/text_hash_value.py +37 -0
  219. whatap/value/text_value.py +43 -0
  220. whatap/value/value.py +26 -0
  221. whatap/value/value_enum.py +80 -0
  222. whatap/whatap.conf +14 -0
  223. whatap_python-2.1.0.dist-info/METADATA +87 -0
  224. whatap_python-2.1.0.dist-info/RECORD +227 -0
  225. whatap_python-2.1.0.dist-info/WHEEL +5 -0
  226. whatap_python-2.1.0.dist-info/entry_points.txt +6 -0
  227. whatap_python-2.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,91 @@
1
+ import sys
2
+
3
+ try:
4
+ from importlib.util import find_spec
5
+ from importlib.abc import MetaPathFinder
6
+ except ImportError:
7
+ find_spec = None
8
+
9
+ from whatap.trace.trace_module_definition import IMPORT_HOOKS, PLUGIN
10
+
11
+ from whatap import logging
12
+ from whatap.conf.configure import Configure as conf
13
+
14
+
15
+ def load_module(module, fullname):
16
+ # if conf.dev:
17
+ # logging.debug(fullname)
18
+
19
+ try:
20
+ if fullname in IMPORT_HOOKS:
21
+ wfullname = IMPORT_HOOKS[fullname]['module']
22
+ wmodule = sys.modules.get(wfullname)
23
+ if not wmodule:
24
+ __import__(wfullname)
25
+ wmodule = sys.modules.get(wfullname)
26
+
27
+ if wfullname.endswith('plugin'):
28
+ module = {'module': module, 'class_defs': PLUGIN[fullname]}
29
+
30
+ getattr(wmodule,
31
+ IMPORT_HOOKS[fullname]['def'])(module)
32
+ logging.info("successfully injected %s as %s", fullname, wfullname)
33
+ else:
34
+ if conf.debug:
35
+ logging.info("non-injected module %s ", fullname)
36
+ except Exception as e:
37
+ logging.debug(e, exc_info=True)
38
+ finally:
39
+ return module
40
+
41
+
42
+ class _ImportHookLoader(object):
43
+ def load_module(self, fullname):
44
+ module = sys.modules[fullname]
45
+ return load_module(module, fullname)
46
+
47
+
48
+ class _ImportHookChainedLoader(object):
49
+ def __init__(self, loader):
50
+ self.loader = loader
51
+
52
+ def load_module(self, fullname):
53
+ module = self.loader.load_module(fullname)
54
+ return load_module(module, fullname)
55
+
56
+
57
+ class ImportFinder(MetaPathFinder):
58
+ def __init__(self):
59
+ self._hooks = {}
60
+
61
+ def find_spec(self, fullname, path=None, target=None):
62
+ if fullname not in IMPORT_HOOKS \
63
+ or fullname.startswith('whatap') \
64
+ or fullname.startswith('pip'):
65
+
66
+ if conf.debug:
67
+ logging.info("non-injected module %s ", fullname)
68
+
69
+ return None
70
+
71
+ if fullname in self._hooks:
72
+ return None
73
+ self._hooks[fullname] = True
74
+
75
+ # if conf.dev:
76
+ # logging.debug(fullname)
77
+
78
+ try:
79
+ if find_spec:
80
+ spec = find_spec(fullname, path)
81
+ if spec and spec.loader:
82
+ spec.loader = _ImportHookChainedLoader(spec.loader)
83
+ return spec
84
+ else:
85
+ __import__(fullname)
86
+ return _ImportHookLoader()
87
+
88
+ except Exception as e:
89
+ if conf.dev:
90
+ print(e)
91
+ return
@@ -0,0 +1,156 @@
1
+ PLUGIN = {}
2
+ IMPORT_HOOKS = {}
3
+
4
+
5
+
6
+ DEFINITION = {
7
+ 'plugin': [
8
+ ('', 'instrument_plugin'),
9
+ ],
10
+ 'standalone': [
11
+ ('', 'instrument_standalone_single'),
12
+ ('', 'instrument_standalone_multiple')
13
+ ],
14
+ 'email.smtp': [
15
+ ('smtplib', 'instrument_smtp'),
16
+ ],
17
+ 'amqp.pika': [
18
+ ('pika.channel', 'instrument_pika'),
19
+ ],
20
+ 'llm.openai': [
21
+ ('openai', 'instrument_openai', 'whatap.llm.providers.openai')
22
+ ],
23
+ 'llm.anthropic': [
24
+ ('anthropic', 'instrument_anthropic', 'whatap.llm.providers.anthropic')
25
+ ],
26
+ 'logging': [
27
+ ('logging.handlers', 'instrument_logging'),
28
+ ('loguru._handler', 'instrument_loguru'),
29
+ ],
30
+
31
+
32
+ 'httpc.httplib': [
33
+ ('httplib', 'instrument_httplib'),
34
+ ('http.client', 'instrument_httplib'),
35
+ ('httplib2', 'instrument_httplib2'),
36
+ ],
37
+ 'httpc.requests': [
38
+ ('requests.sessions', 'instrument_requests'),
39
+ ],
40
+ 'httpc.urllib3': [
41
+ ('urllib3.request', 'instrument_urllib3'),
42
+ ],
43
+ 'httpc.django': [
44
+ ('revproxy.views', 'instrument_revproxy_views'),
45
+ ],
46
+ 'httpc.httpx' : [
47
+ ('httpx', 'instrument_httpx')
48
+ ],
49
+
50
+
51
+ 'database.mysql': [
52
+ ('MySQLdb', 'instrument_MySQLdb'),
53
+ ('MySQLdb.cursors', 'instrument_MySQLdb_cursors'),
54
+ ('pymysql', 'instrument_pymysql'),
55
+ ('pymysql.cursors', 'instrument_pymysql_cursors'),
56
+ ],
57
+ 'database.psycopg2': [
58
+ ('psycopg2', 'instrument_psycopg2'),
59
+ ('psycopg2._psycopg', 'instrument_psycopg2_connection'),
60
+ ('psycopg2.extensions', 'instrument_psycopg2_extensions'),
61
+ ],
62
+ 'database.psycopg3': [
63
+ ('psycopg', 'instrument_psycopg'),
64
+ ('psycopg_pool', 'instrument_psycopg_pool'),
65
+ ],
66
+
67
+ 'database.neo4j': [
68
+ ('neo4j', 'instrument_neo4j')
69
+ ],
70
+ 'database.sqlite3': [
71
+ ('sqlite3', 'instrument_sqlite3')
72
+ ],
73
+ 'database.cxoracle':[
74
+ ('cx_Oracle', 'instrument_oracle_client'),
75
+ ],
76
+ 'database.redis': [
77
+ ('redis', 'instrument_redis_connection'),
78
+ ],
79
+ 'database.mongo': [
80
+ ('pymongo', 'instrument_mongo_client'),
81
+ ],
82
+ 'database.sqlalchemy': [
83
+ ('sqlalchemy.orm.session', 'instrument_sqlalchemy'),
84
+ ('sqlalchemy.engine.default', 'instrument_sqlalchemy_engine'),
85
+ ('sqlalchemy.engine.create', 'instrument_sqlalchemy_engine_basic'),
86
+ ('sqlalchemy.engine', 'instrument_sqlalchemy_engine_basic'),
87
+ ],
88
+ 'database.util': [
89
+ ('', ''),
90
+ ],
91
+
92
+
93
+ 'application.starlette' : [
94
+ ('starlette.websockets' , 'instrument_starlette_websocket'),
95
+ ],
96
+ 'application.wsgi': [
97
+ ('', ''),
98
+ ],
99
+ 'application.bottle': [
100
+ ('bottle', 'instrument'),
101
+ ],
102
+ 'application.cherrypy': [
103
+ ('cherrypy', 'instrument'),
104
+ ],
105
+ 'application.django': [
106
+ ('django.core.handlers.wsgi', 'instrument'),
107
+ ('django.core.handlers.base', 'instrument_handlers_base'),
108
+ ('django.views.generic.base', 'instrument_generic_base'),
109
+ ('django.contrib.staticfiles.handlers', 'instrument_handlers_static'),
110
+ ('channels.http', 'instrument_handlers_channels'),
111
+
112
+ # Django==1.10
113
+ ('django.urls.resolvers', 'instrument_url_resolvers', False),
114
+ ('django.urls.base', 'instrument_urls_base', False),
115
+ ('django.core.handlers.exception', 'instrument_handlers_exception',
116
+ False),
117
+
118
+ ],
119
+ 'application.django_asgi': [
120
+ ('django.core.handlers.asgi', 'instrument_asgi'),
121
+ ],
122
+ 'application.flask': [
123
+ ('flask', 'instrument'),
124
+ ],
125
+ 'application.tornado': [
126
+ ('tornado.web', 'instrument'),
127
+ ],
128
+ 'application.celery': [
129
+ ('celery.execute.trace', 'instrument_celery_execute_trace'),
130
+ ('celery.task.trace', 'instrument_celery_execute_trace'),
131
+ ('celery.app.trace', 'instrument_celery_execute_trace'),
132
+ ],
133
+ 'application.nameko': [
134
+ ('nameko.containers', 'instrument_nameko_spawn_worker'),
135
+ ('spsengine.containers', 'instrument_nameko_spawn_worker'),
136
+ ],
137
+ 'application.graphql':[
138
+ #graphen-core 3.x~
139
+ ('graphql.execution.execute','instrument_graphql'),
140
+
141
+ #graphen-core 2.x
142
+ ('graphql.execution.executor','instrument_graphql'),
143
+ ],
144
+ 'application.fastapi': [
145
+ ('fastapi.applications', 'instrument_applications'),
146
+ ('fastapi.routing', 'instrument'),
147
+ ('fastapi.dependencies.utils', 'instrument_util'),
148
+
149
+ ],
150
+ 'application.frappe': [
151
+ ('frappe.app', 'instrument'),
152
+ ],
153
+ 'application.odoo': [
154
+ ('odoo', 'instrument'),
155
+ ],
156
+ }
File without changes
@@ -0,0 +1,49 @@
1
+ BYTE_MIN_VALUE = -128
2
+ BYTE_MAX_VALUE = 127
3
+ SHORT_MIN_VALUE = -32768
4
+ SHORT_MAX_VALUE = 32767
5
+ INT3_MIN_VALUE = -0x800000
6
+ INT3_MAX_VALUE = 0x007fffff
7
+ INT_MIN_VALUE = -0x80000000
8
+ INT_MAX_VALUE = 0x7fffffff
9
+ LONG5_MIN_VALUE = -0x8000000000
10
+ LONG5_MAX_VALUE = 0x0000007fffffffff
11
+ LONG_MIN_VALUE = -0x8000000000000000
12
+ LONG_MAX_VALUE = 0x7fffffffffffffff
13
+
14
+
15
+ class BitUtil(object):
16
+ @staticmethod
17
+ def composite(hkey, wkey):
18
+ if BYTE_MIN_VALUE <= wkey <= BYTE_MAX_VALUE:
19
+ return (hkey << 8) | (wkey & 0xff)
20
+ elif SHORT_MIN_VALUE <= wkey <= SHORT_MAX_VALUE:
21
+ return (hkey << 16) | (wkey & 0xffff)
22
+ elif INT_MIN_VALUE <= wkey <= INT_MAX_VALUE:
23
+ return (hkey << 32) | (wkey & 0xffffffff)
24
+
25
+ @staticmethod
26
+ def setHigh(src, hkey):
27
+ return (src & 0x00000000ffffffff) | (hkey << 32)
28
+
29
+ @staticmethod
30
+ def setLow(src, wkey):
31
+ return (src & 0xffffffff00000000) | (wkey & 0xffffffff)
32
+
33
+ @staticmethod
34
+ def getHigh(key):
35
+ if SHORT_MIN_VALUE <= key <= SHORT_MAX_VALUE:
36
+ return ((key >> 8) % 0x100000000) & 0xff
37
+ elif INT_MIN_VALUE <= key <= INT_MAX_VALUE:
38
+ return ((key >> 16) % 0x100000000) & 0xffff
39
+ elif LONG_MIN_VALUE <= key <= LONG_MAX_VALUE:
40
+ return ((key >> 32) % 0x100000000) & 0xffffffff
41
+
42
+ @staticmethod
43
+ def getLow(key):
44
+ if SHORT_MIN_VALUE <= key <= SHORT_MAX_VALUE:
45
+ return key & 0xff
46
+ elif INT_MIN_VALUE <= key <= INT_MAX_VALUE:
47
+ return key & 0xffff
48
+ elif LONG_MIN_VALUE <= key <= LONG_MAX_VALUE:
49
+ return key & 0xffffffff
File without changes
@@ -0,0 +1,84 @@
1
+ import math
2
+
3
+ from whatap.io.data_outputx import DataOutputX
4
+ from whatap.util.cardinality.murmurhash import MurMurHash
5
+ from whatap.util.cardinality.registerset import RegisterSet
6
+
7
+
8
+ def getAlphaMM(p, m):
9
+ if p == 4:
10
+ return 0.673 * m * m
11
+ elif p == 5:
12
+ return 0.697 * m * m
13
+ elif p == 6:
14
+ return 0.709 * m * m
15
+ else:
16
+ return (0.7213 / (1 + 1.079 / m)) * m * m
17
+
18
+
19
+ def linearCounting(m, V):
20
+ return m * math.log(m / V)
21
+
22
+
23
+ def numberOfLeadingZeros(i):
24
+ if not i:
25
+ return 32
26
+
27
+ n = 1
28
+ if (i % 0x100000000) >> 16 == 0:
29
+ n += 16
30
+ i <<= 16
31
+ if (i % 0x100000000) >> 24 == 0:
32
+ n += 8
33
+ i <<= 8
34
+ if (i % 0x100000000) >> 28 == 0:
35
+ n += 4
36
+ i <<= 4
37
+ if (i % 0x100000000) >> 30 == 0:
38
+ n += 2
39
+ i <<= 2
40
+
41
+ n -= (i % 0x100000000) >> 31
42
+ return n
43
+
44
+
45
+ class HyperLogLog(object):
46
+ def __init__(self):
47
+ self.log2m = 10
48
+ self.registerSet = RegisterSet(1 << self.log2m)
49
+ m = 1 << self.log2m
50
+ self.alphaMM = getAlphaMM(self.log2m, m)
51
+
52
+ def offerHashed(self, hashedValue):
53
+ j = (hashedValue % 0x100000000) >> (32 - self.log2m)
54
+ r = numberOfLeadingZeros(
55
+ (hashedValue << self.log2m) | (1 << (self.log2m - 1)) + 1) + 1
56
+ return self.registerSet.updateIfGreater(j, r)
57
+
58
+ def offer(self, o):
59
+ x = MurMurHash.hash(o)
60
+ return self.offerHashed(x)
61
+
62
+ def cardinality(self):
63
+ registerSum = 0
64
+ count = self.registerSet.count
65
+ zeros = 0.0
66
+ for j, _ in enumerate(count):
67
+ val = self.registerSet.get(j)
68
+ registerSum += 1.0 / (1 << val)
69
+ if int(val) == 0:
70
+ zeros += 1
71
+
72
+ estimate = self.alphaMM * (1 / registerSum)
73
+ if estimate <= (5.0 / 2.0) * count:
74
+ return math.round(linearCounting(count, zeros))
75
+ else:
76
+ return math.round(estimate)
77
+
78
+ def getBytes(self):
79
+ dout = DataOutputX()
80
+ dout.writeInt(self.log2m)
81
+ dout.writeInt(self.registerSet.size)
82
+ for m in self.registerSet.readOnlyBits():
83
+ dout.writeInt(m)
84
+ return dout.toByteArray()
@@ -0,0 +1,20 @@
1
+ class MurMurHash(object):
2
+ @classmethod
3
+ def hash(cls, data):
4
+ m = 0x5bd1e995
5
+ r = 24
6
+ h = 0
7
+ k = (data * m) & 0xffffffff
8
+ k ^= (k % 0x100000000) >> r
9
+ h ^= (k * m) & 0xffffffff
10
+
11
+ k = ((data >> 32) * m) & 0xffffffff
12
+ k ^= (k % 0x100000000) >> r
13
+ h *= m
14
+ h ^= k * m
15
+
16
+ h ^= (h % 0x100000000) >> 13
17
+ h *= m
18
+ h ^= (h % 0x100000000) >> 15
19
+
20
+ return h
@@ -0,0 +1,60 @@
1
+ LOG2_BITS_PER_WORD = 6
2
+ REGISTER_SIZE = 5
3
+
4
+
5
+ def getBits(count):
6
+ return int(count / LOG2_BITS_PER_WORD)
7
+
8
+
9
+ def getSizeForCount(count):
10
+ bits = getBits(count)
11
+ if not bits:
12
+ return 1
13
+ elif not (bits % 32):
14
+ return bits
15
+ else:
16
+ return bits + 1
17
+
18
+
19
+ class RegisterSet(object):
20
+ def __init__(self, count):
21
+ self.count = count
22
+ self.M = [0 for _ in range(getSizeForCount(self.count))]
23
+ self.size = len(self.M)
24
+
25
+ def set(self, position, value):
26
+ bucketPos = int(position / LOG2_BITS_PER_WORD)
27
+ shift = REGISTER_SIZE * (position - (bucketPos * LOG2_BITS_PER_WORD))
28
+ self.M[bucketPos] = (
29
+ self.M[bucketPos] & ~(0x1f << shift) | (value << shift))
30
+
31
+ def get(self, position):
32
+ bucketPos = int(position / LOG2_BITS_PER_WORD)
33
+ shift = REGISTER_SIZE * (position - (bucketPos * LOG2_BITS_PER_WORD))
34
+ return ((self.M[bucketPos] & (0x1f << shift)) % 0x100000000) >> shift
35
+
36
+ def updateIfGreater(self, position, value):
37
+ bucket = int(position / LOG2_BITS_PER_WORD)
38
+ shift = REGISTER_SIZE * (position - (bucket * LOG2_BITS_PER_WORD))
39
+ mask = 0x1f << shift
40
+
41
+ curVal = self.M[bucket] & mask
42
+ newVal = value << shift
43
+ if curVal < newVal:
44
+ self.M[bucket] = (self.M[bucket] & ~mask) | newVal
45
+ return True
46
+ else:
47
+ return False
48
+
49
+ def merge(self, that):
50
+ for bucket, m in enumerate(self.M):
51
+ word = 0
52
+ for j in range(LOG2_BITS_PER_WORD):
53
+ mask = 0x1f << (REGISTER_SIZE * j)
54
+ thisVal = (self.M[bucket] & mask)
55
+ thatVal = (that.M[bucket] & mask)
56
+ word |= thatVal if thisVal < thatVal else thisVal
57
+ self.M[bucket] = word
58
+
59
+ def readOnlyBits(self):
60
+ return self.M
@@ -0,0 +1,19 @@
1
+ class CompareUtil(object):
2
+
3
+ @staticmethod
4
+ def compareTo(l, r):
5
+ if not l and not r:
6
+ return 0
7
+ elif not l:
8
+ return -1
9
+ elif not r:
10
+ return 1
11
+
12
+ l_ln = len(l)
13
+ r_ln = len(r)
14
+ for i in range(l_ln):
15
+ if l[i] > r[i]:
16
+ return 1
17
+ if l[i] < r[i]:
18
+ return -1
19
+ return l_ln - r_ln
@@ -0,0 +1,55 @@
1
+ import time
2
+
3
+ from datetime import datetime
4
+
5
+
6
+ class DateUtil(object):
7
+ delta = 0
8
+
9
+ MILLIS_PER_SECOND = 1000
10
+ MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND
11
+ MILLIS_PER_FIVE_MINUTE = 5 * 60 * MILLIS_PER_SECOND
12
+ MILLIS_PER_TEN_MINUTE = 10 * MILLIS_PER_MINUTE
13
+ MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE
14
+ MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR
15
+
16
+ @classmethod
17
+ def setServerTime(cls, time, syncfactor):
18
+ now = cls.now()
19
+ delta = time - now
20
+ if delta:
21
+ delta *= syncfactor
22
+ cls.delta = delta
23
+ return cls.delta
24
+
25
+ @classmethod
26
+ def currentTime(cls):
27
+ return int(round(time.time() * 1000)) + cls.delta
28
+
29
+ @classmethod
30
+ def getServerDelta(cls):
31
+ return cls.delta
32
+
33
+ @classmethod
34
+ def now(cls):
35
+ return cls.currentTime()
36
+
37
+ @classmethod
38
+ def nowSystem(cls):
39
+ return int(round(time.time() * 1000))
40
+
41
+ @classmethod
42
+ def getFiveMinUnit(cls):
43
+ return int(int(
44
+ cls.currentTime() / cls.MILLIS_PER_FIVE_MINUTE) * cls.MILLIS_PER_FIVE_MINUTE)
45
+
46
+ @classmethod
47
+ def datetime(cls):
48
+ return datetime.now()
49
+
50
+ @classmethod
51
+ def yyyymmdd(cls, time=None):
52
+ if not time:
53
+ time = cls.currentTime()
54
+ return datetime \
55
+ .fromtimestamp(time / 1000).strftime('%Y%m%d')
@@ -0,0 +1,73 @@
1
+ import threading, traceback, time, sys
2
+ from datetime import datetime, timedelta
3
+
4
+
5
+ def dump_stack(thread_id,output_path, timeout):
6
+ with open(output_path,'a+') as f:
7
+ started = datetime.now()
8
+ while datetime.now() - started < timedelta(seconds=timeout):
9
+ frame = sys._current_frames().get(thread_id)
10
+ if not frame:
11
+ return
12
+ f.write(str(datetime.now()))
13
+ f.write('\n')
14
+ for stack in traceback.extract_stack(frame):
15
+ line = stack[0]
16
+ line_num = stack[1]
17
+ method_name = stack[2]
18
+
19
+ stack = '{} ({}:{})\n'.format(method_name, line, line_num)
20
+ f.write(stack)
21
+ f.write('\n')
22
+ time.sleep(0.5)
23
+
24
+ def dumpThreadStack(timeout, output_path):
25
+ thread_id = threading.get_ident()
26
+
27
+ thr = threading.Thread(target=dump_stack, args=(thread_id,output_path, timeout), kwargs={})
28
+ thr.setDaemon(True)
29
+ thr.start()
30
+
31
+
32
+ def printStack():
33
+ thread_id = threading.get_ident()
34
+
35
+ frame = sys._current_frames().get(thread_id)
36
+ if not frame:
37
+ return
38
+ import io
39
+ f = io.StringIO()
40
+ f.write(str(datetime.now()))
41
+ f.write('\n')
42
+ for stack in traceback.extract_stack(frame):
43
+ line = stack[0]
44
+ line_num = stack[1]
45
+ method_name = stack[2]
46
+
47
+ stack = '{} ({}:{})\n'.format(method_name, line, line_num)
48
+ f.write(stack)
49
+ f.write('\n')
50
+ print(f.getvalue())
51
+
52
+
53
+ def printAllStack():
54
+ for t in threading.enumerate():
55
+ thread_id = t.ident
56
+
57
+ frame = sys._current_frames().get(thread_id)
58
+ if not frame:
59
+ return
60
+
61
+ import io
62
+ f = io.StringIO()
63
+ f.write(str(datetime.now()))
64
+ f.write('\n')
65
+ for stack in traceback.extract_stack(frame):
66
+ line = stack[0]
67
+ line_num = stack[1]
68
+ method_name = stack[2]
69
+
70
+ stack = '{} ({}:{})\n'.format(method_name, line, line_num)
71
+ f.write(stack)
72
+ f.write('\n')
73
+ print(f.getvalue())