[8604] | 1 | ## $Id: sourcefactory.py 11997 2014-11-19 17:02:48Z henrik $ |
---|
| 2 | ## |
---|
| 3 | ## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann |
---|
| 4 | ## This program is free software; you can redistribute it and/or modify |
---|
| 5 | ## it under the terms of the GNU General Public License as published by |
---|
| 6 | ## the Free Software Foundation; either version 2 of the License, or |
---|
| 7 | ## (at your option) any later version. |
---|
| 8 | ## |
---|
| 9 | ## This program is distributed in the hope that it will be useful, |
---|
| 10 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 11 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 12 | ## GNU General Public License for more details. |
---|
| 13 | ## |
---|
| 14 | ## You should have received a copy of the GNU General Public License |
---|
| 15 | ## along with this program; if not, write to the Free Software |
---|
| 16 | ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
| 17 | ## |
---|
| 18 | """Smarter contextual sources, that can do faster containment checks. |
---|
| 19 | """ |
---|
| 20 | import zc.sourcefactory.policies |
---|
| 21 | from zc.sourcefactory.factories import ContextualSourceFactory |
---|
| 22 | from zc.sourcefactory.source import FactoredContextualSource |
---|
| 23 | |
---|
| 24 | class SmartFactoredContextualSource(FactoredContextualSource): |
---|
| 25 | """A contextual source that can be faster. |
---|
| 26 | |
---|
| 27 | Regular ContextualSources from zc.sourcefactory suffer from very |
---|
| 28 | expensive and slow containment checks. __contains__ is executed as |
---|
| 29 | a lookup over the complete set of possible values. |
---|
| 30 | |
---|
| 31 | If, however, a source could do this lookup faster, it had no |
---|
| 32 | chance to do that with regular ContextualSources. |
---|
| 33 | |
---|
| 34 | This source instead looks for a `contains()` method of a |
---|
| 35 | contextual source first and if it has one, this method is called |
---|
| 36 | with `value` and `context` as arguments. |
---|
| 37 | |
---|
| 38 | If a source does not provide `contains()`, the expensive default |
---|
| 39 | lookup method is done instead. |
---|
| 40 | """ |
---|
| 41 | def __contains__(self, value): |
---|
| 42 | """Check whether `value` is part of the source. |
---|
| 43 | |
---|
| 44 | If the factored source provides a `contains(value, context)` |
---|
| 45 | method, this method is called for faster containment |
---|
| 46 | checks. If not, then the getValues() method of a factored |
---|
| 47 | source is used to examine each single item contained in the |
---|
| 48 | source. |
---|
| 49 | """ |
---|
| 50 | if hasattr(self.factory, 'contains'): |
---|
| 51 | return self.factory.contains(self.context, value) |
---|
| 52 | # This is potentially expensive! |
---|
| 53 | return super(SmartFactoredContextualSource, self).__contains__( |
---|
| 54 | value) |
---|
| 55 | |
---|
| 56 | class SmartContextualSourceFactory(ContextualSourceFactory): |
---|
| 57 | source_class = SmartFactoredContextualSource |
---|
| 58 | |
---|
| 59 | class SmartBasicContextualSourceFactory( |
---|
| 60 | SmartContextualSourceFactory, |
---|
| 61 | zc.sourcefactory.policies.BasicContextualSourcePolicy): |
---|
| 62 | """Abstract base implementation for a basic but smart contextual |
---|
| 63 | source factory. |
---|
| 64 | |
---|
| 65 | These factories use any `contains(value, context)` method of |
---|
| 66 | factored sources to speed up containment checks. |
---|
| 67 | |
---|
| 68 | Instances of this class can be used as replacement for |
---|
| 69 | `zc.sourcefactory.BasicContextualSourceFactory`. If your |
---|
| 70 | implementation derived from :class:`SmartBasicContextualFactory` |
---|
| 71 | additionally provides a smart `contains()` method, you only get |
---|
| 72 | benefits from using this class. |
---|
| 73 | |
---|
| 74 | The basic requirements for a working |
---|
| 75 | `SmartBasicContextualSourceFactory` are the same as for regular |
---|
| 76 | ones: you have to implement a `getValues(context)` method. You can |
---|
| 77 | (optionally) implements a `contains(value, context)` method. |
---|
| 78 | """ |
---|