Return-Path: X-Original-To: apmail-cassandra-user-archive@www.apache.org Delivered-To: apmail-cassandra-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 85CEF9589 for ; Fri, 21 Oct 2011 15:53:05 +0000 (UTC) Received: (qmail 60278 invoked by uid 500); 21 Oct 2011 15:53:03 -0000 Delivered-To: apmail-cassandra-user-archive@cassandra.apache.org Received: (qmail 60255 invoked by uid 500); 21 Oct 2011 15:53:03 -0000 Mailing-List: contact user-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@cassandra.apache.org Delivered-To: mailing list user@cassandra.apache.org Received: (qmail 60247 invoked by uid 99); 21 Oct 2011 15:53:03 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 21 Oct 2011 15:53:03 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=5.0 tests=FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of stephen.alan.connolly@gmail.com designates 74.125.82.44 as permitted sender) Received: from [74.125.82.44] (HELO mail-ww0-f44.google.com) (74.125.82.44) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 21 Oct 2011 15:52:59 +0000 Received: by wwe6 with SMTP id 6so4931049wwe.25 for ; Fri, 21 Oct 2011 08:52:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=tBgGy7n4/d+5KxtHd3igNIXn3Q8djtaVD2HBKYuvEeU=; b=DBR2+hyuEiRa+671xRLP5KrF6qN34xdzqyA4PQCYaOUx/Q7rjeclT5IKpP1ZqskkEr NeRMuyfZUeO1IWJkBfgJHHa7fcG6inZ7smfi7GywM2fqU78P/TBerf6YM2MqBd9SP4T4 ztGX8lPPXMlfrXz9gn2dIF9qr8LYuRPML5Vio= MIME-Version: 1.0 Received: by 10.216.229.87 with SMTP id g65mr4056829weq.73.1319212357444; Fri, 21 Oct 2011 08:52:37 -0700 (PDT) Received: by 10.216.198.12 with HTTP; Fri, 21 Oct 2011 08:52:37 -0700 (PDT) In-Reply-To: <4E9BF8C0.8000909@l3s.de> References: <4E95C17C.5000008@l3s.de> <4E95C6C6.2060304@l3s.de> <4E969786.7040208@l3s.de> <4E97186A.5010401@l3s.de> <4E974834.2030205@l3s.de> <4E9BF8C0.8000909@l3s.de> Date: Fri, 21 Oct 2011 16:52:37 +0100 Message-ID: Subject: Re: Storing pre-sorted data From: Stephen Connolly To: user@cassandra.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Well you could use a DOUBLE value to encode relative positions... first item in list gets key 1.0 insert before first item -> key[first]/2.0; append after last item -> key[last]*2.0; insert after non-final item -> (key[n]+key[n+1])/2.0 Using double precision should give you quite a space to fit items... you should be able to cleanly do 2^10 appends, or 2^10 insert first before hitting the significands... and even then you have 2^51 of those... If you start to hit issues like heavy segments, you can re-normalize the ro= w. -Stephen On 17 October 2011 10:43, Matthias Pfau wrote: > Thanks for that hint! However, it seems like soundex is a very language > specific algorithm (US English). We have to get into this topic further..= . > > Kind regards > Matthias > > On 10/13/2011 10:43 PM, Stephen Connolly wrote: >> >> Then just use a soundex function on the first word in the text... that >> will shrink it sufficiently and give nice buckets in near sequential >> order (http://en.wikipedia.org/wiki/Soundex) >> >> On 13 October 2011 21:21, Matthias Pfau =A0wrote: >>> >>> Hi Stephen, >>> we are hashing the first 8 byte (8 US-ASCII characters) of text that ha= s >>> been written by humans. Wouldn't it be easy for the attacker to do a >>> dictionary attack on this text, especially if he knows the language of >>> the >>> text? >>> >>> Kind regards >>> Matthias >>> >>> On 10/13/2011 08:20 PM, Stephen Connolly wrote: >>>> >>>> in theory, however they have less than 32 bits of entropy from which >>>> they can do that, leaving them with at least 32 more bits of >>>> combinations to try... that's 2 billion or so... must be a big >>>> dictionary >>>> >>>> - Stephen >>>> >>>> --- >>>> Sent from my Android phone, so random spelling mistakes, random nonsen= se >>>> words and other nonsense are a direct result of using swype to type on >>>> the screen >>>> >>>> On 13 Oct 2011 17:57, "Matthias Pfau"> >>>> wrote: >>>> >>>> =A0 =A0Hi Stephen, >>>> =A0 =A0this sounds very reasonable. But wouldn't this enable an attack= er to >>>> =A0 =A0execute dictionary attacks in order to "decrypt" the first 8 by= tes >>>> =A0 =A0of the plain text? >>>> >>>> =A0 =A0Kind regards >>>> =A0 =A0Matthias >>>> >>>> =A0 =A0On 10/13/2011 05:03 PM, Stephen Connolly wrote: >>>> >>>> =A0 =A0 =A0 =A0It wouldn't be unencrypted... which is the point >>>> >>>> =A0 =A0 =A0 =A0you use a one way linear hash function to take the firs= t, say 8 >>>> =A0 =A0 =A0 =A0bytes, >>>> =A0 =A0 =A0 =A0of unencrypted data and turn it into 4 bytes of a sort = prefix. >>>> >>>> =A0 =A0 =A0 =A0You've used lost half the data in the process, so effec= tively >>>> =A0 =A0 =A0 =A0each bit >>>> =A0 =A0 =A0 =A0is an OR of two bits and you can only infer from 0 valu= es... so >>>> data >>>> =A0 =A0 =A0 =A0is still encrypted, but you have an approximate sorting= . >>>> >>>> =A0 =A0 =A0 =A0For example, if your data is US-ASCII text with no numb= ers, you >>>> =A0 =A0 =A0 =A0could >>>> =A0 =A0 =A0 =A0use Soundex to get the pre-key, so that worst case you = have a >>>> bucket >>>> =A0 =A0 =A0 =A0of values in the range. >>>> >>>> =A0 =A0 =A0 =A0Using this technique, a random get will have to get the= values >>>> =A0 =A0 =A0 =A0at the >>>> =A0 =A0 =A0 =A0desired prefix +/- a small amount rather than the whole= row... >>>> =A0 =A0 =A0 =A0on the >>>> =A0 =A0 =A0 =A0client side you can then decrypt the data and sort that= small >>>> bucket >>>> =A0 =A0 =A0 =A0to get the correct index position. >>>> >>>> =A0 =A0 =A0 =A0You could do a 1 byte prefix, but that only gives you a= t best 256 >>>> =A0 =A0 =A0 =A0buckets and assumes that the first 2 bytes are uniforml= y >>>> =A0 =A0 =A0 =A0distributed... you've said your data is not uniformly >>>> =A0 =A0 =A0 =A0distributed, so >>>> =A0 =A0 =A0 =A0a linear hash function sounds like your best bet. >>>> >>>> =A0 =A0 =A0 =A0your hash function should have the property that hash(A= )>=3D >>>> =A0 =A0 =A0 =A0hash(B) if >>>> =A0 =A0 =A0 =A0and only if A>=3D B >>>> >>>> =A0 =A0 =A0 =A0On 13 October 2011 08:47, Matthias Pfau>>> =A0 =A0 =A0 =A0> =A0 =A0wrote: >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0Hi Stephen, >>>> =A0 =A0 =A0 =A0 =A0 =A0this is a great idea but unfortunately doesn't = work for us >>>> =A0 =A0 =A0 =A0 =A0 =A0either as we can >>>> =A0 =A0 =A0 =A0 =A0 =A0not store the data in an unencrypted form. >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0Kind regards >>>> =A0 =A0 =A0 =A0 =A0 =A0Matthias >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0On 10/12/2011 07:42 PM, Stephen Connolly wrote: >>>> >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0could you prefix the data with 3-4 byte= s of a linear >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0hash of the >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unencypted data? it wouldn't be a perfe= ct sort, but >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0you'd have less of a >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0range to query to get the sorted values= ? >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0- Stephen >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0--- >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Sent from my Android phone, so random s= pelling mistakes, >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0random nonsense >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0words and other nonsense are a direct r= esult of using >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0swype to type on >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0the screen >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0On 12 Oct 2011 17:57, "Matthias Pfau">>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0wrote: >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Unfortunately, that is not an o= ption as we have to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0store the data in >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0an compressed and encrypted and= therefore binary and >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0non-sortable form. >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0On 10/12/2011 06:39 PM, David M= cNelis wrote: >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Is it an option to not = convert the data to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0binary prior to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0inserting >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0into Cassandra? =A0Also= , how large are the strings >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0you're sorting? >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0If its >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0viable to not convert t= o binary before writing >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0to Cassandra, and >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0you use >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0one of the string based= column ordering >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0techniques (utf8, ascii, >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0example), then the data= would be sorted without >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0you =A0needing to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0specifically worry abou= t that. =A0Of course, if >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0the strings are >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lengthy >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0you could run into =A0a= dditional issues. >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0On Wed, Oct 12, 2011 at= 11:34 AM, Matthias >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Pfau >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= > >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0>>> =A0 =A0wrote: >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Hi there, >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0we are currentl= y building a prototype based >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0on cassandra and >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0came >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0into problems o= n implementing sorted lists >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0containing >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0millions of items. >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0The special thi= ng about the items of our >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lists is, that >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cassandra is >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0not able to sor= t them as the data is stored >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0in a binary >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0format which >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0is not sortable= . However, we are able to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0sort the data >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0before the >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0plain data gets= encoded (our application is >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0responsible for >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0the order). >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0First Approach:= Storing Lists in >>>> ColumnFamilies >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*** >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0We first tried = to map the list to a single >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0row of a >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ColumnFamily in >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0a way that the = index of the list is mapped >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0to the column >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0names and >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0the items of th= e list to the column values. >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0The column names >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0are >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0increasing numb= ers which define the sort >>>> order. >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0This has the ma= jor drawback that big parts >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0of the list have >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0to be >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0rewritten on in= serts (because the column >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0names are numbered >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0by their >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0index), which a= re quite common. >>>> >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Second Approach= : Storing the whole List as >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Binary Data: >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*** >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0We tried to sto= re the compressed list in a >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0single column. >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0However, >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0this is only fe= asible for smaller lists. Our >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0lists are far >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0to big >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0leading to mult= i megabyte reads and writes. >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0As we need to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0read and >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0update the list= s quite often, this would put >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0our Cassandra >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cluster >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0under a lot of = pressure. >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Ideal Solution:= Native support for storing >>>> lists >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*** >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0We would be ver= y happy with a way to store a >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0list of sorted >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0values >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0without making = improper use of column names >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for the list >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0index. This >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0implies that we= would need a possibility to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0insert values at >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0defined >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0positions. We k= now that this could lead to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0problems with >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0concurrent >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0inserts in a di= stributed environment, but >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0this is handled by >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0our >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0application log= ic. >>>> >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0What are your i= deas on that? >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Thanks >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Matthias >>>> >>>> >>>> >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*David McNelis* >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Lead Software Engineer >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Agentis Energy >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0www.agentisenergy.com >>>> >>>> =A0>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0c: 219.384.5143 >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0> >>>> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/A Smart Grid technolog= y company focused on >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0helping consumers of >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0energy >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0control an often under-= managed resource./ >>>> >>>> >>>> >>>> >>>> >>>> >>> >>> > >