/Data/ZoomCache/Numeric/Int.hs

https://github.com/kfish/zoom-cache · Haskell · 725 lines · 396 code · 112 blank · 217 comment · 0 complexity · 2151cb4d2457b0501e2a25c0e83f576a MD5 · raw file

  1. {-# LANGUAGE BangPatterns #-}
  2. {-# LANGUAGE CPP #-}
  3. {-# LANGUAGE FlexibleContexts #-}
  4. {-# LANGUAGE FlexibleInstances #-}
  5. {-# LANGUAGE OverloadedStrings #-}
  6. {-# LANGUAGE RecordWildCards #-}
  7. {-# LANGUAGE TypeFamilies #-}
  8. {-# OPTIONS_GHC -Wall -fno-warn-orphans #-}
  9. ----------------------------------------------------------------------
  10. {- |
  11. Module : Data.ZoomCache.Numeric.Int
  12. Copyright : Conrad Parker
  13. License : BSD3-style (see LICENSE)
  14. Maintainer : Conrad Parker <conrad@metadecks.org>
  15. Stability : unstable
  16. Portability : unknown
  17. Default codec implementation for values of type Int. This module
  18. implements the interfaces documented in "Data.ZoomCache.Codec".
  19. View the module source for enlightenment.
  20. The table below describes the encoding of SummaryData for Int8:
  21. @
  22. | ... | -35
  23. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  24. | Entry (int8) | Exit (int8) | Min (int8) | Max (int8) | 36-39
  25. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  26. | Avg (double) | 40-43
  27. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  28. | | 44-47
  29. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  30. | RMS (double) | 48-51
  31. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  32. @
  33. The table below describes the encoding of SummaryData for Int16:
  34. @
  35. | ... | -35
  36. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  37. | Entry (int16) | Exit (int16) | 36-39
  38. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  39. | Min (int16) | Max (int16) | 40-43
  40. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  41. | Avg (double) | 44-47
  42. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  43. | | 48-51
  44. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  45. | RMS (double) | 52-55
  46. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  47. | | 56-59
  48. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  49. @
  50. The table below describes the encoding of SummaryData for Int32:
  51. @
  52. | ... | -35
  53. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  54. | Entry (int32) | 36-39
  55. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  56. | Exit (int32) | 40-43
  57. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  58. | Min (int32) | 44-47
  59. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  60. | Max (int32) | 48-51
  61. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  62. | Avg (double) | 52-55
  63. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  64. | | 56-59
  65. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  66. | RMS (double) | 60-63
  67. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  68. | | 64-67
  69. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  70. @
  71. The table below describes the encoding of SummaryData for Int64:
  72. @
  73. | ... | -35
  74. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  75. | Entry (int64) | 36-39
  76. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  77. | | 40-43
  78. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  79. | Exit (int64) | 44-47
  80. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  81. | | 48-51
  82. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  83. | Min (int64) | 52-55
  84. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  85. | | 56-59
  86. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  87. | Max (int64) | 60-63
  88. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  89. | | 64-67
  90. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  91. | Avg (double) | 68-71
  92. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  93. | | 72-75
  94. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  95. | RMS (double) | 76-79
  96. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  97. | | 80-83
  98. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  99. @
  100. SummaryData for Int and Integer is encoded as the following sequence:
  101. @
  102. Entry (intVLC)
  103. Exit (intVLC)
  104. Min (intVLC)
  105. Max (intVLC)
  106. Avg (double)
  107. RMS (double)
  108. @
  109. Field encoding formats:
  110. @int8@: 8bit signed integer
  111. @int16@: 16bit big endian signed integer
  112. @int32@: 32bit big endian signed integer
  113. @int64@: 32bit big endian signed integer
  114. @intVLC@: Variable-length-coded signed integer
  115. @double@: big-endian IEEE 754-2008 binary64 (IEEE 754-1985 double)
  116. Variable-length coding format:
  117. zoom-cache includes a simple variable-length coding scheme for signed integers.
  118. When decoding, single bytes are read at a time. If the high bit is set, the
  119. next byte is also read. The lower 7 bits of each byte contain data. Decoding
  120. continues by reading single bytes until a byte is read with the high bit zero.
  121. The first byte of a variable-length coded integer contain a sign bit and the
  122. lowest 6 bits of the value. This byte is encoded as:
  123. @
  124. 0 1 2 3 4 5 6 7
  125. +-+-+-+-+-+-+-+-+
  126. |s| d[0]-d[5] |c|
  127. +-+-+-+-+-+-+-+-+
  128. @
  129. Subsequent bytes encode bits 6-12, 13-19, ... of the value:
  130. @
  131. 0 1 2 3 4 5 6 7
  132. +-+-+-+-+-+-+-+-+
  133. | d[n]-d[n+6] |c|
  134. +-+-+-+-+-+-+-+-+
  135. @
  136. where @n = 6, 13, 20, ...@
  137. @s@: sign, 1 = negative, 0 = non-negative
  138. @c@: continue flag, 1 = continue reading next byte, 0 = stop
  139. -}
  140. ----------------------------------------------------------------------
  141. module Data.ZoomCache.Numeric.Int (
  142. SummaryData(..)
  143. , SummaryWork(..)
  144. )where
  145. #if __GLASGOW_HASKELL__ >= 702
  146. import Data.ByteString (ByteString)
  147. import Data.Iteratee (Iteratee)
  148. #endif
  149. import Blaze.ByteString.Builder
  150. import Control.Applicative ((<$>))
  151. import Data.Int
  152. import Data.Maybe (fromMaybe)
  153. import Text.Printf
  154. import Data.ZoomCache.Codec
  155. import Data.ZoomCache.Numeric.Internal
  156. import Data.ZoomCache.Numeric.Types
  157. ----------------------------------------------------------------------
  158. -- Int
  159. instance ZoomReadable Int where
  160. data SummaryData Int = SummaryInt
  161. { summaryIntEntry :: {-# UNPACK #-}!Int
  162. , summaryIntExit :: {-# UNPACK #-}!Int
  163. , summaryIntMin :: {-# UNPACK #-}!Int
  164. , summaryIntMax :: {-# UNPACK #-}!Int
  165. , summaryIntAvg :: {-# UNPACK #-}!Double
  166. , summaryIntRMS :: {-# UNPACK #-}!Double
  167. }
  168. trackIdentifier = const "ZOOMintb"
  169. readRaw = fromIntegral <$> readIntegerVLC
  170. readSummary = readSummaryNum
  171. prettyRaw = show
  172. prettySummaryData = prettySummaryInt
  173. deltaDecodeRaw = deltaDecodeNum
  174. #if __GLASGOW_HASKELL__ >= 702
  175. {-# SPECIALIZE readSummaryNum :: (Functor m, Monad m) => Iteratee ByteString m (SummaryData Int) #-}
  176. #endif
  177. instance ZoomWrite Int where
  178. write = writeData
  179. instance ZoomWrite (SampleOffset, Int) where
  180. write = writeDataVBR
  181. instance ZoomWrite (TimeStamp, Int) where
  182. write = writeDataTS
  183. instance ZoomWritable Int where
  184. data SummaryWork Int = SummaryWorkInt
  185. { swIntTime :: {-# UNPACK #-}!SampleOffset
  186. , swIntEntry :: !(Maybe Int)
  187. , swIntExit :: {-# UNPACK #-}!Int
  188. , swIntMin :: {-# UNPACK #-}!Int
  189. , swIntMax :: {-# UNPACK #-}!Int
  190. , swIntSum :: {-# UNPACK #-}!Double
  191. , swIntSumSq :: {-# UNPACK #-}!Double
  192. }
  193. fromRaw = fromIntegerVLC . fromIntegral
  194. fromSummaryData = fromSummaryNum
  195. initSummaryWork = initSummaryNumBounded
  196. toSummaryData = mkSummaryNum
  197. updateSummaryData = updateSummaryNum
  198. appendSummaryData = appendSummaryNum
  199. deltaEncodeRaw = deltaEncodeNum
  200. instance ZoomNum Int where
  201. numEntry = summaryIntEntry
  202. numExit = summaryIntExit
  203. numMin = summaryIntMin
  204. numMax = summaryIntMax
  205. numAvg = summaryIntAvg
  206. numRMS = summaryIntRMS
  207. numWorkSO = swIntTime
  208. numWorkEntry = swIntEntry
  209. numWorkExit = swIntExit
  210. numWorkMin = swIntMin
  211. numWorkMax = swIntMax
  212. numWorkSum = swIntSum
  213. numWorkSumSq = swIntSumSq
  214. numMkSummary = SummaryInt
  215. numMkSummaryWork = SummaryWorkInt
  216. #if __GLASGOW_HASKELL__ >= 702
  217. {-# SPECIALIZE fromSummaryNum :: SummaryData Int -> Builder #-}
  218. {-# SPECIALIZE initSummaryNumBounded :: SampleOffset -> SummaryWork Int #-}
  219. {-# SPECIALIZE mkSummaryNum :: SampleOffsetDiff -> SummaryWork Int -> SummaryData Int #-}
  220. {-# SPECIALIZE appendSummaryNum :: SampleOffsetDiff -> SummaryData Int -> SampleOffsetDiff -> SummaryData Int -> SummaryData Int #-}
  221. {-# SPECIALIZE updateSummaryNum :: SampleOffset -> Int -> SummaryWork Int -> SummaryWork Int #-}
  222. #endif
  223. ----------------------------------------------------------------------
  224. -- Int8
  225. instance ZoomReadable Int8 where
  226. data SummaryData Int8 = SummaryInt8
  227. { summaryInt8Entry :: {-# UNPACK #-}!Int8
  228. , summaryInt8Exit :: {-# UNPACK #-}!Int8
  229. , summaryInt8Min :: {-# UNPACK #-}!Int8
  230. , summaryInt8Max :: {-# UNPACK #-}!Int8
  231. , summaryInt8Avg :: {-# UNPACK #-}!Double
  232. , summaryInt8RMS :: {-# UNPACK #-}!Double
  233. }
  234. trackIdentifier = const "ZOOMiS8b"
  235. readRaw = readInt8
  236. readSummary = readSummaryNum
  237. prettyRaw = show
  238. prettySummaryData = prettySummaryInt
  239. deltaDecodeRaw = deltaDecodeNum
  240. #if __GLASGOW_HASKELL__ >= 702
  241. {-# SPECIALIZE readSummaryNum :: (Functor m, Monad m) => Iteratee ByteString m (SummaryData Int8) #-}
  242. #endif
  243. instance ZoomWrite Int8 where
  244. write = writeData
  245. instance ZoomWrite (SampleOffset, Int8) where
  246. write = writeDataVBR
  247. instance ZoomWrite (TimeStamp, Int8) where
  248. write = writeDataTS
  249. instance ZoomWritable Int8 where
  250. data SummaryWork Int8 = SummaryWorkInt8
  251. { swInt8Time :: {-# UNPACK #-}!SampleOffset
  252. , swInt8Entry :: !(Maybe Int8)
  253. , swInt8Exit :: {-# UNPACK #-}!Int8
  254. , swInt8Min :: {-# UNPACK #-}!Int8
  255. , swInt8Max :: {-# UNPACK #-}!Int8
  256. , swInt8Sum :: {-# UNPACK #-}!Double
  257. , swInt8SumSq :: {-# UNPACK #-}!Double
  258. }
  259. fromRaw = fromInt8
  260. fromSummaryData = fromSummaryNum
  261. initSummaryWork = initSummaryNumBounded
  262. toSummaryData = mkSummaryNum
  263. updateSummaryData = updateSummaryNum
  264. appendSummaryData = appendSummaryNum
  265. deltaEncodeRaw = deltaEncodeNum
  266. instance ZoomNum Int8 where
  267. numEntry = summaryInt8Entry
  268. numExit = summaryInt8Exit
  269. numMin = summaryInt8Min
  270. numMax = summaryInt8Max
  271. numAvg = summaryInt8Avg
  272. numRMS = summaryInt8RMS
  273. numWorkSO = swInt8Time
  274. numWorkEntry = swInt8Entry
  275. numWorkExit = swInt8Exit
  276. numWorkMin = swInt8Min
  277. numWorkMax = swInt8Max
  278. numWorkSum = swInt8Sum
  279. numWorkSumSq = swInt8SumSq
  280. numMkSummary = SummaryInt8
  281. numMkSummaryWork = SummaryWorkInt8
  282. #if __GLASGOW_HASKELL__ >= 702
  283. {-# SPECIALIZE fromSummaryNum :: SummaryData Int8 -> Builder #-}
  284. {-# SPECIALIZE initSummaryNumBounded :: SampleOffset -> SummaryWork Int8 #-}
  285. {-# SPECIALIZE mkSummaryNum :: SampleOffsetDiff -> SummaryWork Int8 -> SummaryData Int8 #-}
  286. {-# SPECIALIZE appendSummaryNum :: SampleOffsetDiff -> SummaryData Int8 -> SampleOffsetDiff -> SummaryData Int8 -> SummaryData Int8 #-}
  287. {-# SPECIALIZE updateSummaryNum :: SampleOffset -> Int8 -> SummaryWork Int8 -> SummaryWork Int8 #-}
  288. #endif
  289. ----------------------------------------------------------------------
  290. -- Int16
  291. instance ZoomReadable Int16 where
  292. data SummaryData Int16 = SummaryInt16
  293. { summaryInt16Entry :: {-# UNPACK #-}!Int16
  294. , summaryInt16Exit :: {-# UNPACK #-}!Int16
  295. , summaryInt16Min :: {-# UNPACK #-}!Int16
  296. , summaryInt16Max :: {-# UNPACK #-}!Int16
  297. , summaryInt16Avg :: {-# UNPACK #-}!Double
  298. , summaryInt16RMS :: {-# UNPACK #-}!Double
  299. }
  300. trackIdentifier = const "ZOOMi16b"
  301. readRaw = readInt16be
  302. readSummary = readSummaryNum
  303. prettyRaw = show
  304. prettySummaryData = prettySummaryInt
  305. deltaDecodeRaw = deltaDecodeNum
  306. #if __GLASGOW_HASKELL__ >= 702
  307. {-# SPECIALIZE readSummaryNum :: (Functor m, Monad m) => Iteratee ByteString m (SummaryData Int16) #-}
  308. #endif
  309. instance ZoomWrite Int16 where
  310. write = writeData
  311. instance ZoomWrite (SampleOffset, Int16) where
  312. write = writeDataVBR
  313. instance ZoomWrite (TimeStamp, Int16) where
  314. write = writeDataTS
  315. instance ZoomWritable Int16 where
  316. data SummaryWork Int16 = SummaryWorkInt16
  317. { swInt16Time :: {-# UNPACK #-}!SampleOffset
  318. , swInt16Entry :: !(Maybe Int16)
  319. , swInt16Exit :: {-# UNPACK #-}!Int16
  320. , swInt16Min :: {-# UNPACK #-}!Int16
  321. , swInt16Max :: {-# UNPACK #-}!Int16
  322. , swInt16Sum :: {-# UNPACK #-}!Double
  323. , swInt16SumSq :: {-# UNPACK #-}!Double
  324. }
  325. fromRaw = fromInt16be
  326. fromSummaryData = fromSummaryNum
  327. initSummaryWork = initSummaryNumBounded
  328. toSummaryData = mkSummaryNum
  329. updateSummaryData = updateSummaryNum
  330. appendSummaryData = appendSummaryNum
  331. deltaEncodeRaw = deltaEncodeNum
  332. instance ZoomNum Int16 where
  333. numEntry = summaryInt16Entry
  334. numExit = summaryInt16Exit
  335. numMin = summaryInt16Min
  336. numMax = summaryInt16Max
  337. numAvg = summaryInt16Avg
  338. numRMS = summaryInt16RMS
  339. numWorkSO = swInt16Time
  340. numWorkEntry = swInt16Entry
  341. numWorkExit = swInt16Exit
  342. numWorkMin = swInt16Min
  343. numWorkMax = swInt16Max
  344. numWorkSum = swInt16Sum
  345. numWorkSumSq = swInt16SumSq
  346. numMkSummary = SummaryInt16
  347. numMkSummaryWork = SummaryWorkInt16
  348. #if __GLASGOW_HASKELL__ >= 702
  349. {-# SPECIALIZE fromSummaryNum :: SummaryData Int16 -> Builder #-}
  350. {-# SPECIALIZE initSummaryNumBounded :: SampleOffset -> SummaryWork Int16 #-}
  351. {-# SPECIALIZE mkSummaryNum :: SampleOffsetDiff -> SummaryWork Int16 -> SummaryData Int16 #-}
  352. {-# SPECIALIZE appendSummaryNum :: SampleOffsetDiff -> SummaryData Int16 -> SampleOffsetDiff -> SummaryData Int16 -> SummaryData Int16 #-}
  353. {-# SPECIALIZE updateSummaryNum :: SampleOffset -> Int16 -> SummaryWork Int16 -> SummaryWork Int16 #-}
  354. #endif
  355. ----------------------------------------------------------------------
  356. -- Int32
  357. instance ZoomReadable Int32 where
  358. data SummaryData Int32 = SummaryInt32
  359. { summaryInt32Entry :: {-# UNPACK #-}!Int32
  360. , summaryInt32Exit :: {-# UNPACK #-}!Int32
  361. , summaryInt32Min :: {-# UNPACK #-}!Int32
  362. , summaryInt32Max :: {-# UNPACK #-}!Int32
  363. , summaryInt32Avg :: {-# UNPACK #-}!Double
  364. , summaryInt32RMS :: {-# UNPACK #-}!Double
  365. }
  366. trackIdentifier = const "ZOOMi32b"
  367. readRaw = readInt32be
  368. readSummary = readSummaryNum
  369. prettyRaw = show
  370. prettySummaryData = prettySummaryInt
  371. deltaDecodeRaw = deltaDecodeNum
  372. #if __GLASGOW_HASKELL__ >= 702
  373. {-# SPECIALIZE readSummaryNum :: (Functor m, Monad m) => Iteratee ByteString m (SummaryData Int32) #-}
  374. #endif
  375. instance ZoomWrite Int32 where
  376. write = writeData
  377. instance ZoomWrite (SampleOffset, Int32) where
  378. write = writeDataVBR
  379. instance ZoomWrite (TimeStamp, Int32) where
  380. write = writeDataTS
  381. instance ZoomWritable Int32 where
  382. data SummaryWork Int32 = SummaryWorkInt32
  383. { swInt32Time :: {-# UNPACK #-}!SampleOffset
  384. , swInt32Entry :: !(Maybe Int32)
  385. , swInt32Exit :: {-# UNPACK #-}!Int32
  386. , swInt32Min :: {-# UNPACK #-}!Int32
  387. , swInt32Max :: {-# UNPACK #-}!Int32
  388. , swInt32Sum :: {-# UNPACK #-}!Double
  389. , swInt32SumSq :: {-# UNPACK #-}!Double
  390. }
  391. fromRaw = fromIntegral32be
  392. fromSummaryData = fromSummaryNum
  393. initSummaryWork = initSummaryNumBounded
  394. toSummaryData = mkSummaryNum
  395. updateSummaryData = updateSummaryNum
  396. appendSummaryData = appendSummaryNum
  397. deltaEncodeRaw = deltaEncodeNum
  398. instance ZoomNum Int32 where
  399. numEntry = summaryInt32Entry
  400. numExit = summaryInt32Exit
  401. numMin = summaryInt32Min
  402. numMax = summaryInt32Max
  403. numAvg = summaryInt32Avg
  404. numRMS = summaryInt32RMS
  405. numWorkSO = swInt32Time
  406. numWorkEntry = swInt32Entry
  407. numWorkExit = swInt32Exit
  408. numWorkMin = swInt32Min
  409. numWorkMax = swInt32Max
  410. numWorkSum = swInt32Sum
  411. numWorkSumSq = swInt32SumSq
  412. numMkSummary = SummaryInt32
  413. numMkSummaryWork = SummaryWorkInt32
  414. #if __GLASGOW_HASKELL__ >= 702
  415. {-# SPECIALIZE fromSummaryNum :: SummaryData Int32 -> Builder #-}
  416. {-# SPECIALIZE initSummaryNumBounded :: SampleOffset -> SummaryWork Int32 #-}
  417. {-# SPECIALIZE mkSummaryNum :: SampleOffsetDiff -> SummaryWork Int32 -> SummaryData Int32 #-}
  418. {-# SPECIALIZE appendSummaryNum :: SampleOffsetDiff -> SummaryData Int32 -> SampleOffsetDiff -> SummaryData Int32 -> SummaryData Int32 #-}
  419. {-# SPECIALIZE updateSummaryNum :: SampleOffset -> Int32 -> SummaryWork Int32 -> SummaryWork Int32 #-}
  420. #endif
  421. ----------------------------------------------------------------------
  422. -- Int64
  423. instance ZoomReadable Int64 where
  424. data SummaryData Int64 = SummaryInt64
  425. { summaryInt64Entry :: {-# UNPACK #-}!Int64
  426. , summaryInt64Exit :: {-# UNPACK #-}!Int64
  427. , summaryInt64Min :: {-# UNPACK #-}!Int64
  428. , summaryInt64Max :: {-# UNPACK #-}!Int64
  429. , summaryInt64Avg :: {-# UNPACK #-}!Double
  430. , summaryInt64RMS :: {-# UNPACK #-}!Double
  431. }
  432. trackIdentifier = const "ZOOMi64b"
  433. readRaw = readInt64be
  434. readSummary = readSummaryNum
  435. prettyRaw = show
  436. prettySummaryData = prettySummaryInt
  437. deltaDecodeRaw = deltaDecodeNum
  438. #if __GLASGOW_HASKELL__ >= 702
  439. {-# SPECIALIZE readSummaryNum :: (Functor m, Monad m) => Iteratee ByteString m (SummaryData Int64) #-}
  440. #endif
  441. instance ZoomWrite Int64 where
  442. write = writeData
  443. instance ZoomWrite (SampleOffset, Int64) where
  444. write = writeDataVBR
  445. instance ZoomWrite (TimeStamp, Int64) where
  446. write = writeDataTS
  447. instance ZoomWritable Int64 where
  448. data SummaryWork Int64 = SummaryWorkInt64
  449. { swInt64Time :: {-# UNPACK #-}!SampleOffset
  450. , swInt64Entry :: !(Maybe Int64)
  451. , swInt64Exit :: {-# UNPACK #-}!Int64
  452. , swInt64Min :: {-# UNPACK #-}!Int64
  453. , swInt64Max :: {-# UNPACK #-}!Int64
  454. , swInt64Sum :: {-# UNPACK #-}!Double
  455. , swInt64SumSq :: {-# UNPACK #-}!Double
  456. }
  457. fromRaw = fromInt64be
  458. fromSummaryData = fromSummaryNum
  459. initSummaryWork = initSummaryNumBounded
  460. toSummaryData = mkSummaryNum
  461. updateSummaryData = updateSummaryNum
  462. appendSummaryData = appendSummaryNum
  463. deltaEncodeRaw = deltaEncodeNum
  464. instance ZoomNum Int64 where
  465. numEntry = summaryInt64Entry
  466. numExit = summaryInt64Exit
  467. numMin = summaryInt64Min
  468. numMax = summaryInt64Max
  469. numAvg = summaryInt64Avg
  470. numRMS = summaryInt64RMS
  471. numWorkSO = swInt64Time
  472. numWorkEntry = swInt64Entry
  473. numWorkExit = swInt64Exit
  474. numWorkMin = swInt64Min
  475. numWorkMax = swInt64Max
  476. numWorkSum = swInt64Sum
  477. numWorkSumSq = swInt64SumSq
  478. numMkSummary = SummaryInt64
  479. numMkSummaryWork = SummaryWorkInt64
  480. #if __GLASGOW_HASKELL__ >= 702
  481. {-# SPECIALIZE fromSummaryNum :: SummaryData Int64 -> Builder #-}
  482. {-# SPECIALIZE initSummaryNumBounded :: SampleOffset -> SummaryWork Int64 #-}
  483. {-# SPECIALIZE mkSummaryNum :: SampleOffsetDiff -> SummaryWork Int64 -> SummaryData Int64 #-}
  484. {-# SPECIALIZE appendSummaryNum :: SampleOffsetDiff -> SummaryData Int64 -> SampleOffsetDiff -> SummaryData Int64 -> SummaryData Int64 #-}
  485. {-# SPECIALIZE updateSummaryNum :: SampleOffset -> Int64 -> SummaryWork Int64 -> SummaryWork Int64 #-}
  486. #endif
  487. ----------------------------------------------------------------------
  488. -- Integer
  489. instance ZoomReadable Integer where
  490. data SummaryData Integer = SummaryInteger
  491. { summaryIntegerEntry :: !Integer
  492. , summaryIntegerExit :: !Integer
  493. , summaryIntegerMin :: !Integer
  494. , summaryIntegerMax :: !Integer
  495. , summaryIntegerAvg :: {-# UNPACK #-}!Double
  496. , summaryIntegerRMS :: {-# UNPACK #-}!Double
  497. }
  498. trackIdentifier = const "ZOOMintb"
  499. readRaw = readIntegerVLC
  500. readSummary = readSummaryNum
  501. prettyRaw = show
  502. prettySummaryData = prettySummaryInt
  503. deltaDecodeRaw = deltaDecodeNum
  504. #if __GLASGOW_HASKELL__ >= 702
  505. {-# SPECIALIZE readSummaryNum :: (Functor m, Monad m) => Iteratee ByteString m (SummaryData Integer) #-}
  506. #endif
  507. instance ZoomWrite Integer where
  508. write = writeData
  509. instance ZoomWrite (SampleOffset, Integer) where
  510. write = writeDataVBR
  511. instance ZoomWrite (TimeStamp, Integer) where
  512. write = writeDataTS
  513. instance ZoomWritable Integer where
  514. data SummaryWork Integer = SummaryWorkInteger
  515. { swIntegerTime :: {-# UNPACK #-}!SampleOffset
  516. , swIntegerEntry :: !(Maybe Integer)
  517. , swIntegerExit :: !Integer
  518. , swIntegerMin :: !(Maybe Integer)
  519. , swIntegerMax :: !(Maybe Integer)
  520. , swIntegerSum :: {-# UNPACK #-}!Double
  521. , swIntegerSumSq :: {-# UNPACK #-}!Double
  522. }
  523. fromRaw = fromIntegerVLC
  524. fromSummaryData = fromSummaryNum
  525. initSummaryWork = initSummaryInteger
  526. toSummaryData = toSummaryInteger
  527. updateSummaryData = updateSummaryInteger
  528. appendSummaryData = appendSummaryNum
  529. deltaEncodeRaw = deltaEncodeNum
  530. instance ZoomNum Integer where
  531. numEntry = summaryIntegerEntry
  532. numExit = summaryIntegerExit
  533. numMin = summaryIntegerMin
  534. numMax = summaryIntegerMax
  535. numAvg = summaryIntegerAvg
  536. numRMS = summaryIntegerRMS
  537. numWorkSO = swIntegerTime
  538. numWorkEntry = swIntegerEntry
  539. numWorkExit = swIntegerExit
  540. numWorkMin = error "numWorkMin undefined for Integer"
  541. numWorkMax = error "numWorkMax undefined for Integer"
  542. numWorkSum = swIntegerSum
  543. numWorkSumSq = swIntegerSumSq
  544. numMkSummary = SummaryInteger
  545. numMkSummaryWork = error "numMkSummaryWork undefined for Integer"
  546. #if __GLASGOW_HASKELL__ >= 702
  547. {-# SPECIALIZE fromSummaryNum :: SummaryData Integer -> Builder #-}
  548. {-# SPECIALIZE mkSummaryNum :: SampleOffsetDiff -> SummaryWork Integer -> SummaryData Integer #-}
  549. {-# SPECIALIZE appendSummaryNum :: SampleOffsetDiff -> SummaryData Integer -> SampleOffsetDiff -> SummaryData Integer -> SummaryData Integer #-}
  550. {-# SPECIALIZE updateSummaryNum :: SampleOffset -> Integer -> SummaryWork Integer -> SummaryWork Integer #-}
  551. #endif
  552. initSummaryInteger :: SampleOffset -> SummaryWork Integer
  553. initSummaryInteger entry = SummaryWorkInteger entry Nothing 0 Nothing Nothing 0.0 0.0
  554. toSummaryInteger :: SampleOffsetDiff -> SummaryWork Integer -> SummaryData Integer
  555. toSummaryInteger (SODiff dur) SummaryWorkInteger{..} = SummaryInteger
  556. { summaryIntegerEntry = fromMaybe 0 swIntegerEntry
  557. , summaryIntegerExit = swIntegerExit
  558. , summaryIntegerMin = fromMaybe 0 swIntegerMin
  559. , summaryIntegerMax = fromMaybe 0 swIntegerMax
  560. , summaryIntegerAvg = swIntegerSum / fromIntegral dur
  561. , summaryIntegerRMS = sqrt $ swIntegerSumSq / fromIntegral dur
  562. }
  563. updateSummaryInteger :: SampleOffset -> Integer
  564. -> SummaryWork Integer
  565. -> SummaryWork Integer
  566. updateSummaryInteger t d SummaryWorkInteger{..} = SummaryWorkInteger
  567. { swIntegerTime = t
  568. , swIntegerEntry = Just $ fromMaybe d swIntegerEntry
  569. , swIntegerExit = d
  570. , swIntegerMin = Just $ fromMaybe d swIntegerMin
  571. , swIntegerMax = Just $ fromMaybe d swIntegerMax
  572. , swIntegerSum = swIntegerSum + realToFrac (d * fromIntegral dur)
  573. , swIntegerSumSq = swIntegerSumSq + realToFrac (d*d * fromIntegral dur)
  574. }
  575. where
  576. !(SODiff dur) = sampleOffsetDiff t swIntegerTime
  577. ----------------------------------------------------------------------
  578. prettySummaryInt :: (PrintfArg a, ZoomNum a)
  579. => SummaryData a -> String
  580. prettySummaryInt s = concat
  581. [ printf "\tentry: %d\texit: %df\tmin: %d\tmax: %d\t"
  582. (numEntry s) (numExit s) (numMin s) (numMax s)
  583. , printf "avg: %.3f\trms: %.3f" (numAvg s) (numRMS s)
  584. ]