1487{
1488 DWORD prev_time, last_irec_time;
1489 int fh, fhd, fhi, cp = 0;
1490 std::string fn, fnd, fni;
1491 int delta;
1493 int cache_size;
1499 char *cache = NULL;
1500 time_t ltime;
1501
1502 int tag_index = -1;
1503 int var_type = -1;
1504 unsigned var_size = 0;
1505 unsigned var_offset = 0;
1506
1507 int ieof = 0;
1508
1509
1510
1512
1513
1514 if (start_time == 0)
1515 start_time = (
DWORD) time(NULL) - 3600;
1516 if (end_time == 0)
1517 end_time = (
DWORD) time(NULL);
1518
1519 if (data_n)
1520 *data_n = 0;
1521 prev_time = 0;
1522 last_irec_time = start_time;
1523
1524
1527
1528 if (data_n)
1529 *data_n = 0;
1530 if (tbsize)
1531 *tbsize = 0;
1532 if (dbsize)
1533 *dbsize = 0;
1535 }
1536
1537
1541 if (fh < 0 || fhd < 0 || fhi < 0) {
1543 if (tbsize)
1544 *tbsize = 0;
1545 if (dbsize)
1546 *dbsize = 0;
1547 if (data_n)
1548 *data_n = 0;
1549 if (fh > 0)
1550 close(fh);
1551 if (fhd > 0)
1552 close(fhd);
1553 if (fhi > 0)
1554 close(fhi);
1556 }
1557
1558
1560 cache_size =
xcurpos(fni, fhi);
1561
1562 if (cache_size == 0) {
1563 goto nextday;
1564 }
1565
1566 if (cache_size > 0) {
1567 cache = (
char *)
M_MALLOC(cache_size);
1568 if (cache) {
1570 if (
xread(fni, fhi, cache, cache_size) < 0) {
1572 if (fh > 0)
1573 close(fh);
1574 if (fhd > 0)
1575 close(fhd);
1576 if (fhi > 0)
1577 close(fhi);
1579 }
1580 }
1581
1582
1583 if (cache == NULL) {
1585 delta = (
xcurpos(fni, fhi) /
sizeof(irec)) / 2;
1586 xseek(fni, fhi, delta *
sizeof(irec));
1587 do {
1588 delta = (int) (abs(delta) / 2.0 + 0.5);
1589 if (
xread(fni, fhi, (
char *) &irec,
sizeof(irec)) < 0)
1591 if (irec.time > start_time)
1592 delta = -delta;
1593
1594 xseek_cur(fni, fhi, (delta - 1) *
sizeof(irec));
1595 } while (abs(delta) > 1 && irec.time != start_time);
1596 if (
xread(fni, fhi, (
char *) &irec,
sizeof(irec)) < 0)
1598 if (irec.time > start_time)
1599 delta = -abs(delta);
1600
1601 int i =
xcurpos(fni, fhi) + (delta - 1) *
sizeof(irec);
1604 else
1605 xseek_cur(fni, fhi, (delta - 1) *
sizeof(irec));
1606 if (
xread(fni, fhi, (
char *) &irec,
sizeof(irec)) < 0)
1608 } else {
1609 delta = (cache_size / sizeof(irec)) / 2;
1610 cp = delta * sizeof(irec);
1611 do {
1612 delta = (int) (abs(delta) / 2.0 + 0.5);
1614
1615
1616
1617 if (pirec->
time > start_time)
1618 delta = -delta;
1619
1620 cp = cp + delta * sizeof(irec);
1621
1622 if (cp < 0)
1623 cp = 0;
1624 if (cp >= cache_size)
1625 cp = cache_size - sizeof(irec);
1626 }
while (abs(delta) > 1 && pirec->
time != start_time);
1628 if (pirec->
time > start_time)
1629 delta = -abs(delta);
1630
1631 if (cp <= delta * (int) sizeof(irec))
1632 cp = 0;
1633 else
1634 cp = cp + delta * sizeof(irec);
1635
1636 if (cp >= cache_size)
1637 cp = cache_size - sizeof(irec);
1638 if (cp < 0)
1639 cp = 0;
1640
1641 memcpy(&irec, (
INDEX_RECORD *) (cache + cp),
sizeof(irec));
1642 cp += sizeof(irec);
1643 }
1644 } else {
1645
1646 cache = NULL;
1647 irec.time = start_time;
1648 }
1649
1650
1651 old_def_offset = -1;
1652 last_irec_time = start_time - 24 * 60 * 60;
1653 do {
1654
1655
1656 if (irec.time < last_irec_time) {
1657 cm_msg(
MERROR,
"hs_read",
"corrupted history data: time does not increase: %d -> %d", last_irec_time, irec.time);
1658
1659 if (fh > 0)
1660 close(fh);
1661 if (fhd > 0)
1662 close(fhd);
1663 if (fhi > 0)
1664 close(fhi);
1667 }
1668 last_irec_time = irec.time;
1669 if (irec.event_id ==
event_id && irec.time <= end_time && irec.time >= start_time) {
1670
1671 if (irec.time >= prev_time + interval) {
1672 prev_time = irec.time;
1673 xseek(fn, fh, irec.offset);
1674 if (
xread(fn, fh, (
char *) &rec,
sizeof(rec)) < 0) {
1675 cm_msg(
MERROR,
"hs_read",
"corrupted history data at time %d", (
int) irec.time);
1676
1677 if (fh > 0)
1678 close(fh);
1679 if (fhd > 0)
1680 close(fhd);
1681 if (fhi > 0)
1682 close(fhi);
1685 }
1686
1687
1688 if ((
INT) rec.def_offset != old_def_offset) {
1689 xseek(fn, fh, rec.def_offset);
1690 xread(fn, fh, (
char *) &drec,
sizeof(drec));
1692
1694 if (tag == NULL) {
1695 if (data_n)
1696 *data_n = 0;
1697 if (tbsize)
1698 *tbsize = 0;
1699 if (dbsize)
1700 *dbsize = 0;
1701 if (cache)
1703 if (fh > 0)
1704 close(fh);
1705 if (fhd > 0)
1706 close(fhd);
1707 if (fhi > 0)
1708 close(fhi);
1710 }
1711 xread(fn, fh, (
char *) tag, drec.data_size);
1712
1713
1714 for (
DWORD i = 0;
i < drec.data_size /
sizeof(
TAG);
i++)
1717 break;
1718 }
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731 if (tag_index >= 0 && var_index >= tag[tag_index].n_data) {
1732 if (data_n)
1733 *data_n = 0;
1734 if (tbsize)
1735 *tbsize = 0;
1736 if (dbsize)
1737 *dbsize = 0;
1738 if (cache)
1741 if (fh > 0)
1742 close(fh);
1743 if (fhd > 0)
1744 close(fhd);
1745 if (fhi > 0)
1746 close(fhi);
1748 }
1749
1750
1751 if (tag_index >= 0) {
1752 var_type = tag[tag_index].
type;
1753
1754 if (data_type)
1755 *data_type = var_type;
1756
1757
1758 var_offset = 0;
1759 for (
int i=0;
i<tag_index;
i++)
1761
1762
1764 var_size = tag[tag_index].
n_data;
1765 else
1767
1768 var_offset += var_size * var_index;
1769 }
1770
1772 old_def_offset = rec.def_offset;
1773 xseek(fn, fh, irec.offset +
sizeof(rec));
1774 }
1775
1776 if (buffer) {
1777
1778 DWORD t = irec.time;
1779 char buf[16];
1780 assert(var_size <= sizeof(buf));
1782 xread(fn, fh, buf, var_size);
1784 } else if (tag_index >= 0 && data_n) {
1785
1786 if ((*data_n) *
sizeof(
DWORD) >= *tbsize || (*data_n) * var_size >= *dbsize) {
1787 *dbsize = (*data_n) * var_size;
1788 *tbsize = (*data_n) *
sizeof(
DWORD);
1789 if (cache)
1791 if (fh > 0)
1792 close(fh);
1793 if (fhd > 0)
1794 close(fhd);
1795 if (fhi > 0)
1796 close(fhi);
1798 }
1799
1800
1801 time_buffer[*data_n] = irec.time;
1802
1803
1805 xread(fn, fh, (
char *) data_buffer + (*data_n) * var_size, var_size);
1806
1807
1808 (*data_n)++;
1809 }
1810 }
1811 }
1812
1813
1814 if (cache) {
1815 if (cp >= cache_size) {
1816 ieof = -1;
1818 cache = NULL;
1819 } else {
1820
1821 try_again:
1822
1823 ieof = sizeof(irec);
1824
1825 memcpy(&irec, cache + cp, sizeof(irec));
1826 cp += sizeof(irec);
1827
1828
1829 if (irec.time < last_irec_time || irec.time > last_irec_time + 24 * 60 * 60) {
1830
1831
1832
1833
1834
1835 while (cp < cache_size) {
1838
1839 goto try_again;
1840 }
1841
1842 cp++;
1843 }
1844
1845 ieof = -1;
1846 }
1847 }
1848 } else {
1849 ieof =
xread(fni, fhi, (
char *) &irec,
sizeof(irec),
true);
1850 }
1851
1852
1853 if (ieof <= 0) {
1854 nextday:
1855
1856 if (fh > 0)
1857 close(fh);
1858 if (fhd > 0)
1859 close(fhd);
1860 if (fhi > 0)
1861 close(fhi);
1862 fh = fhd = fhi = 0;
1863
1864
1865 ltime = (time_t) last_irec_time;
1867 localtime_r(<ime, &tms);
1868 tms.tm_hour = tms.tm_min = tms.tm_sec = 0;
1870
1871 last_irec_time += 3600 * 24;
1872
1873 if (last_irec_time > end_time)
1874 break;
1875
1876
1879 break;
1880
1881
1882 hs_open_file(last_irec_time,
"hst", O_RDONLY, &fn, &fh);
1883 hs_open_file(last_irec_time,
"idf", O_RDONLY, &fnd, &fhd);
1884 hs_open_file(last_irec_time,
"idx", O_RDONLY, &fni, &fhi);
1885 if (fh < 0 || fhd < 0 || fhi < 0) {
1887 break;
1888 }
1889
1890
1892 cache_size =
xcurpos(fni, fhi);
1893
1894 if (cache_size == 0) {
1895 goto nextday;
1896 }
1897
1899 cache = (
char *)
M_MALLOC(cache_size);
1900 if (cache) {
1901 if (
xread(fni, fhi, cache, cache_size) < 0) {
1902 break;
1903 }
1904
1905 cp = 0;
1906 memcpy(&irec, cache, sizeof(irec));
1907 } else {
1908
1909 if (
xread(fni, fhi, (
char *) &irec,
sizeof(irec)) < 0) {
1910 break;
1911 }
1912 }
1913
1914
1915 old_def_offset = -1;
1916 }
1917
1918
1919 } while (irec.time < end_time);
1920
1921 if (cache)
1923 if (fh)
1924 close(fh);
1925 if (fhd)
1926 close(fhd);
1927 if (fhi)
1928 close(fhi);
1929
1930 if (dbsize && data_n)
1931 *dbsize = *data_n * var_size;
1932 if (tbsize && data_n)
1933 *tbsize = *data_n *
sizeof(
DWORD);
1934
1936}
virtual void Add(time_t time, double value)=0
double hs_to_double(int tid, const void *ybuffer)