1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*-
2 : #ifndef EPT_POPCON_POPCON_H
3 : #define EPT_POPCON_POPCON_H
4 :
5 : /** @file
6 : * @author Enrico Zini <enrico@enricozini.org>
7 : * Access popcon data
8 : */
9 :
10 : /*
11 : * Copyright (C) 2007 Enrico Zini <enrico@debian.org>
12 : *
13 : * This program is free software; you can redistribute it and/or modify
14 : * it under the terms of the GNU General Public License as published by
15 : * the Free Software Foundation; either version 2 of the License, or
16 : * (at your option) any later version.
17 : *
18 : * This program is distributed in the hope that it will be useful,
19 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : * GNU General Public License for more details.
22 : *
23 : * You should have received a copy of the GNU General Public License
24 : * along with this program; if not, write to the Free Software
25 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 : */
27 :
28 : #include <tagcoll/diskindex/mmap.h>
29 : #include <string>
30 :
31 : namespace ept {
32 : namespace apt {
33 : class Apt;
34 : }
35 :
36 : namespace popcon {
37 :
38 : /**
39 : * Store the score information in the popcon cache.
40 : *
41 : * Currently, this is only one float; more can be added in the future.
42 : */
43 : class Score
44 : {
45 : protected:
46 : unsigned offset;
47 :
48 : public:
49 : float score;
50 :
51 69910 : Score(float score) : offset(offset), score(score) {}
52 :
53 : friend class Popcon;
54 : friend class PopconIndexer;
55 : friend class PopconGenerator;
56 : };
57 :
58 : /**
59 : * Maps Packages to IDs and vice-versa.
60 : *
61 : * This is used in building the Debtags fast index, which works representing
62 : * tags and packages as int IDs.
63 : *
64 : * Index building works like this:
65 : * 1. The file all-popcon-results.txt.gz is downloaded from
66 : * http://popcon.debian.org/all-popcon-results.txt.gz
67 : * 2. The file is put in either ~/.popcon/all-popcon-results.txt.gz
68 : * or in /var/lib/popcon/all-popcon-results.txt.gz
69 : * 3. If the file is newer than the index, it will be automatically used to
70 : * recompute the scores and rebuild the index.
71 : */
72 : class Popcon : public tagcoll::diskindex::MMap
73 7 : {
74 : struct GeneralInfo : public tagcoll::diskindex::MMap
75 7 : {
76 : size_t submissions() const;
77 : };
78 :
79 : tagcoll::diskindex::MasterMMap mastermmap;
80 : time_t m_timestamp;
81 :
82 : GeneralInfo m_info;
83 :
84 : /// Get the score structure by index
85 102350 : const Score* structByIndex(size_t idx) const
86 : {
87 102350 : if (idx >= 0 && idx < size())
88 102350 : return (Score*)m_buf + idx;
89 0 : return 0;
90 : }
91 :
92 : public:
93 : Popcon();
94 :
95 : /// Get the timestamp of when the index was last updated
96 1 : time_t timestamp() const { return m_timestamp; }
97 :
98 : /// Return true if this data source has data, false if it's empty
99 1 : bool hasData() const { return m_timestamp != 0; }
100 :
101 : /// Return the total number of popcon submissions
102 3 : size_t submissions() const { return m_info.submissions(); }
103 :
104 : /// Get the number of packages in the index
105 174055 : size_t size() const
106 : {
107 174055 : if (m_buf)
108 174053 : return ((Score*)m_buf)->offset / sizeof(Score);
109 : else
110 2 : return 0;
111 : }
112 :
113 : /**
114 : * Get a package name by index
115 : *
116 : * If the index is not valid, returns the empty string.
117 : */
118 30678 : std::string name(size_t idx) const
119 : {
120 30678 : const Score* s = structByIndex(idx);
121 30678 : if (s == 0) return std::string();
122 30678 : return std::string(m_buf + s->offset);
123 : }
124 :
125 : /// Get the score by index
126 71672 : float scoreByIndex(size_t idx) const
127 : {
128 71672 : const Score* s = structByIndex(idx);
129 71672 : if (!s) return 0;
130 71672 : return s->score;
131 : }
132 :
133 : /// Get the score structure by package name
134 : float scoreByName(const std::string& name) const;
135 :
136 : /// Get the score by index
137 71672 : float score(size_t idx) const { return scoreByIndex(idx); }
138 :
139 : /// Get the score by index
140 : float operator[](int idx) const { return scoreByIndex(idx); }
141 :
142 : /// Get the score by name
143 1790 : float score(const std::string& name) const { return scoreByName(name); }
144 :
145 : /// Get the score structure by package name
146 2 : float operator[](const std::string& name) const { return scoreByName(name); }
147 : };
148 :
149 : }
150 : }
151 :
152 : // vim:set ts=4 sw=4:
153 : #endif
|