text:
'); jQuery("#searchform").css("display","block") jQuery(".nav").css("display","block") var n = 280; jQuery(".off-sidebar").click(function() { if(jQuery("body").hasClass("show-sidebar")) { jQuery("#content").animate({left: 0}, 250), jQuery("body").removeClass("show-sidebar") } else { jQuery("#content").animate({left: n}, 250), jQuery("body").addClass("show-sidebar") } }); } });
Progressive culture since 1954
Our prizes
By Nicky Hager
219 Winter 2015
On 2 October last year, five detectives and a police computer expert spent ten and a half hours raiding my home. They took all of the phones, computers, hard drives, USB keys, CDs and other electronic devices, as well as an assortment of files.
They were trying to uncover the identity of a confidential source who had given me information for my recently published book about New Zealand politics. The book had revealed a campaign of dirty tricks being run out of the prime minister's office, including an organised system for smears on political opponents.
But I'm sleeping easy; I'm as certain as I can be that the raid was a waste of the police's time. It won't help them at all to find my source.
This is an issue vexing investigative journalists around the world: how to protect sensitive sources in the era of widespread surveillance technologies. I have heard a lot of pessimism about how it is no longer possible to keep confidential sources safe – sources here meaning whistleblowers and people who leak important public-interest information. I don't agree. Investigative journalism is as possible and powerful as ever. I believe that if we understand the risks and do our job properly, we can continue to protect our sources, as I was able to do with the sources for my recent book.
I love the work of investigative journalism. For people with the right aptitude and motivation, it is one of the most socially useful things they can do. I want to share with you a sense of what this work is, how it is done and why it is so worth doing. But first I want to start with the subject of protecting sources in the digital age.
The first thing the police looked for when they arrived at my house – the first thing they always look for – was my mobile phone; they were rather crestfallen to learn that I do not use one. (I know this is unusual, but in my work I prefer mental space to immediate availability.) Mobile phones are pretty much self-surveillance devices for people who have things they need to keep confidential. They are also one of the main ways that police investigate crimes: by seizing a phone, the police instantly get an alphabetised list of friends and associates, piles of text messages with dates and times of activities, often a GPS record of your movements, photos with embedded times and locations, and more.
Over the years I have written quite a lot about police and intelligence, and so I understand many aspects of how investigations are handled. I certainly don't believe the NSA and satellites track me wherever I go or anything like that. They don't. But whether you're a shoplifter or a whistleblower, mobile phones are the most likely way you will be traced. For this reason anyone with a sensitive source should never use their phone to contact said source.
You may have heard stories of the lengths people will go to avoid interception, such as removing the batteries from their mobiles or sticking them in the fridge. In truth, most people who imagine they are being spied on are worrying for nothing. But if there is a serious need to be careful, such as protecting a sensitive source, people just shouldn't use mobiles. Leave them at home – it's as simple as that.
The main reason is metadata, that word that firmly entered the modern vernacular with Edward Snowden. In practice, the police do not bug many phones. It takes too many resources to listen to and transcribe spoken conversations, and so the practice is generally reserved for serious crimes. But 'call data' or 'metadata' – easy and readily available – is the police's investigative tool of choice. Call data includes the records of who you called, when you called and the location of the nearest cellphone tower. The same databases that save this data also save all text messages to and from your phone. In New Zealand, this data is automatically saved for all mobile phones for three to four months; in Australia, courtesy of the recent amendments to the Telecommunications (Interception and Access) Act, this data will be stored for at least two years. The police routinely phone or email the telcos and get this information to help their investigations.
The solution to this is awareness. We shouldn't meet a confidential source in a busy cafe and, likewise, we shouldn't leave great big digital footprints between ourselves and our precious and vulnerable sources. Many sources are caught, particularly in government agencies, because the agency owns and stores all its phone logs. When there is a leak investigation, they can do obvious checks such as any incoming or outgoing calls from the journalist who did the story. We just need to understand the risks and, when it matters, never leave electronic tracks.
So how do I contact sources or potential sources? Usually it's a face-to-face encounter, or sometimes I call from an untraceable phone. After that it's at prearranged meetings set up the last time we saw each other. Sometimes high-tech, but usually simple and low-tech. I do not encrypt my email or waste time worrying about surveillance for 99.9 per cent of my communications – but I do make sure I am very careful when it is needed.
The next thing the police looked for in my house were any computers. My main computer, like many people's, contains mountains of emails plotting my life hour by hour. But I have always made sure there were no tracks to the source of my book. (Incidentally, deleting something on most computers doesn't remove it entirely.)
Even in the unlucky event that the police win the current court case and are granted access to my computer, they will find that the hard drive is encrypted and has a nice long password. A six- or seven-letter password can be cracked in quite a short time by a simple computer program that tries a, aa, ab, aaa, aab and so on. Thus, each additional symbol in a password makes it much harder to crack.
I am not a computer whiz. For such tasks I seek out very experienced IT people to help with things like computer encryption. I find that collaboration between investigative journalists and IT whizzes is a very productive matching of skills.
I should add that the kind of precautions I'm talking about here aren't needed for most situations. I don't think countries like Australia and New Zealand have armies of secret police taking an unhealthy interest in everything we do. Indeed, I spend my life reassuring people that they really don't need to worry about being under personal surveillance. But sometimes we do need to take it seriously – for example, when it comes to protecting confidential sources.
The most important protections are the basic pre-digital ones, in particular knowing how to keep a secret. Not being able to do this is, in fact, the biggest risk.
Many people cannot keep a secret. Secrets create an irresistible urge to share. If we 'just tell one person', they are likely to tell someone else who cares even less about keeping the secret and – by natural laws of physics – the news accelerates outwards.
I say to sources: 'We need to put a fence around the two of us and never tell anyone else what we're doing for the rest of our lives.' It is simple and effective. It means there are some marvellous stories that can't be told, but there is no alternative. Part of a journalist–source relationship is being there to give care and support to your source, especially early on when they are feeling vulnerable. In most cases, the people who have helped me reveal big stories seem to feel pride and satisfaction in what they have achieved. Often a special life-long bond is formed.
The final step in protecting sources is the care needed when writing the story. The facts that we know and those that we don't know can be like a great big arrow pointing at a few people as possible informants, and so it is vital that great care is taken in how this information is presented. The specialists brought in to study a government or corporate leak go first for the organisational call data – logs of who accessed which documents and so on. Next, they study what details are in the story, which have been omitted, what years the information covers, which staff know what bits of information and thus, by triangulation, who their suspects are.
Once we understand this, we can take precautions. I picture a security officer studying a leak, and go to great effort selecting what information to include, what to leave out, where to supplement from other sources and, generally, how to bewilder those trying to narrow down where the leak came from. I often find that, as I write, I am putting as much thought into what I might give away about my sources as to what I am writing. This faithfulness to sources is part of my job.
If we are careful and do all of these things, I genuinely believe we can continue to get new sources and keep them safe. I feel confident that sources such as the one the police were hoping to identify in the raid on my house will be just fine.
What I am saying is this: we can still work with sources to hold powerful people to account and to inform the public on big issues – and keep them safe in the process.
This leads to the big question: why? Why should journalists and sources risk themselves for the sake of a story? What purpose does investigative journalism serve?
Daily news is reasonably good at reporting what 'newsmakers' say and do in public, and blogs and commentators are good – sometimes very good – at discussing and analysing that news. But the media system is weak when things are hidden, spun or manipulated – in other words, when it relies on press releases or other controlled messaging. It's a weakness that becomes apparent as soon as there are organised vested interests that have the resources and motivation to try to control information reaching the public, or to spin a preferred version of truth.
Investigative journalism is the activity of unearthing and publicising things that challenge dominant views: finding out who is telling the truth, exposing unethical behaviour or dishonesty, giving a voice to people and issues that are hidden or ignored, digging deep on behalf of the public so that people don't have to live in a political soup of spin and half-truth. It is about providing a counter-narrative to that of the powerful.
It's not easy work, but it can be highly satisfying and worthwhile.
In recent years there have been some stunning, world-changing leaks, notably those inspired by WikiLeaks. Those leaks will undoubtedly lead to more people deciding to make important disclosures of a similar scale. But although there are similarities, that kind of leaking is not the same thing as investigative journalism.
Sometimes I wonder if those stunning revelations and information dumps have made it seem as if leaks just turn up on their own; perhaps giving the impression that investigative journalism is about setting up a secure cloud account on the internet and waiting for the leaks to come to you.
The heart of investigative journalism – and when I enjoy it most – is when you decide a subject needs investigating and set about digging down into the roots of the issue. It is a very strategic activity: studying a subject and then searching for the right investigative tools and sources to make progress. Personally, I have many subjects that I feel need work (and that are on 'the list') and I continue to search gradually for the right sources and breakthroughs.
When I start such an investigation, I make a 'map' of what sorts of things I want to find out about a subject and include all the possible sources (people and otherwise) that might help. I draw up lists of places where I would like to find insiders and make a register of fieldwork to be done, letters to write, experts to ask, overseas parallels to research and so on. Sometimes it's like a game or puzzle: I'm trying to solve a problem, find a missing clue. Often, because I am working on subjects that are secretive or intentionally hidden, I am looking for insiders and sensitive material.
And then, usually, a kind of magic occurs. I find that if I have bothered to think through what I'm trying to find, and brainstormed the types of sources I am looking for, they tend to come along. I unexpectedly meet someone who can help, or hear about a source of information that might be useful. Somehow, perhaps because I was on the lookout, the breakthrough happens.
This has worked for me so many times now – my first book in 1996 was about New Zealand's role in the Five Eyes intelligence network, and others followed on the military in Afghanistan, anti-environmental public relations and the inner workings of governments and political parties – that I have come to realise that if I do the work, I have a good chance of getting results.
But it's not really magic – indeed, some of my subjects haven't worked out at all yet. It is really a combination of planning, luck and then hard work.
Most inside sources who have helped me would never dream of being a Chelsea Manning or Edward Snowden. It would not even occur to them, or at least not seriously, to approach a journalist and become a whistleblower. Partly, this is why the secure dropbox is not enough. The vast majority of sources help because I have sought them out and asked. I have been able to reassure them that there is value in publicising the issue and that they can trust me not to get them into trouble.
That is my secret method: asking.
It is hugely important that potential sources continue to feel comfortable saying yes, and that there are journalists who keep seeking them out and asking for information. Many of the terrible issues in the world rely on secrecy; control of information and selected release of spin are part of how bad things can happen in relatively democratic and law-based countries. Insiders are often the only realistic way of getting information about hidden things. If people in power believe they can get away with keeping their actions classified, they generally act much worse than if they risk finding their grubby business or lies suddenly exposed on the front page.
But having willing sources is only half of the equation. One of the challenges for investigative journalism is not having enough people to seek out potential sources. And who is going to do that kind of work in increasingly stripped down and precarious news organisations?
I think we need to recognise that investigative journalism isn't just a speciality within the journalism field. Much of the best investigative work is done by filmmakers, authors and public-interest researchers, people who might not see themselves as traditional journalists but who are still fulfilling this critical role. It is a role in society defined by its goals, tools, methods and motivations, not by job descriptions and university qualifications.
Countries don't need hundreds of investigative journalists, but they need some – and the more the better! Every issue and every part of society that has decent investigative journalism is better off than the many areas that have no scrutiny. I have been part of international networks of investigative journalists for the last twenty or so years. Country by country, there are people who have done inspiring pieces of public-interest research that have helped to change the world.
Take, for instance, the Swedish TV journalist Fredrik Laurin, who felt suspicious when reading a government statement about deporting two men to Egypt in the early years of the so-called War on Terror. The government said that it had an assurance from the Egyptian government that the men would not be tortured, which is like an assurance from soft drink companies that they care about obesity. He went back to the film footage he'd taken of the aircraft taking off and found the aircraft's tail number, N379P. By searching on the net he found a story about the same plane collecting hooded detainees from an airfield in Pakistan, further spurring his curiosity. He followed this with letters to plane spotters around the world, asking about more sightings of the plane, which was registered to a US company with no office or staff, only an address in a legal office. Step by careful step, he and colleagues gradually uncovered one of the really important stories of that era: the CIA's 'rendition' flights, which were used to grab suspects from around the world and illegally move them to secret detention centres or Guantanamo Bay.
It makes me happy to know that people like Fredrik exist. We have worked together on other projects since then.
Similarly, one evening when I was in Switzerland, I had dinner with a South African investigative journalist named Justin Arenstein. He told me a story about an investigation he had conducted into vicious vigilante teams set up by white farmers to intimidate and punish black farm workers. He had moved into a rural area, ostensibly to look after a friend's farm for a few months, and it wasn't long before his neighbours encouraged him to do his bit to enforce their version of justice. Set up with hidden cameras, he went out on hair-raising night-time drives to sort out – that is, threaten and assault – the black workers. When Arenstein's exposé eventually came out, the country was shocked; the vigilante numbers decreased and the authorities were forced to stop secretly supporting them.
There are many more such stories. There is the Indian journalist catching corrupt politicians, the Mozambique journalist exposing illegal rainforest logging, others publicising unsafe factories all over the world or illegal fishing or countless other subjects. These journalists often make a profound difference to the problem they are reporting on: they uncover it, thereby stopping it being invisible or hidden.
The ones I respect the most are those who have kept going through the decades, continuing to uncover big stories and resisting the urge to be cynical or discouraged. It is always easier to decide that the world is a mess and that nothing can be done about it. In every era through history there is plenty of bad and depressing news to justify thinking the future is hopeless. But society has nonetheless made progress, and each era is much better than it would have been because people continue to be shocked and offended by injustice and inhumanity. And, crucially, some people do something about that.
Finally, there is a related 'occupation' that is worth mentioning. It is for people who work in governments, companies, political parties, PR firms and all sorts of other places, in senior or junior roles, who come across information of public interest and decide to tip off or pass those details on to people like me. You may one day find yourself in that position, as part of your career, or in a job you take to earn money for a while. If you find things that offend you and that the public has a right to know, then – with suitable care and thought – you can maybe do some good by working with a trustworthy investigative journalist to get that story told.
That is what happened with the main source for my last book – the one the police were looking for and, all going well, will never find. They did New Zealand a massive service by helping to expose the activities of the dirtiest prime minister in our lifetimes.
Overland is a not-for-profit magazine with a proud history of supporting writers, and publishing ideas and voices often excluded from other places.
If you like this piece, or support Overland 's work in general, please subscribe or donate.
Nicky Hager works as an investigative journalist and author. He has written six books about New Zealand politics, intelligence, the environment, public relations and military subjects. His most recent book was Dirty Politics, how attack politics is poisoning New Zealand's political environment.
More by Nicky Hager
This article was published in 219 Winter 2015
t Follow on Twitter
f Like on Facebook
Verity on Fiction | A child's six
Colin Walpole on 2019 Winner of Queensland Poetry Award's Older Emerging Poets Mentorship Prize: Julie Manning
John Muk Muk on Why cops don't deserve a float at Mardi Gras
Wayne Eaton on The atrocity exhibition
Sally Ryhanen on Fiction | A child's six
236 Spring 2019
Speculative future(s)
Future Sex (fiction)
Subscribe to Overland
Donate to Overland
Judith Wright (poetry)
Neilma Sidney (fiction)
Nakata Brophy
VU Short Story Prize
Fair Australia Prize
Pitch work
Writing prizes
© 2021 Overland literary journal


text:
Q: How to update element style in Dash callback I am using dash cytoscape to draw a tree plot. I want to be able to update the style of a terminal node using a Dash callback. I can get the callback to run and output the updated style, but the figure does not update, I'm guessing this is because of the diffing method used. I have tried returning the stylesheet as part of the callback as well as this was suggested in another post. Can anyone offer any suggestions as to how I can get the style to update?

A: You can add an item 'type' to your element 'data' key and then add a selector for this type on your stylesheet. For example :
          style_sheet = {
                            'selector': '[type = "your_type"]',
                            'style': {
                                'background-color': '#9cd0e2',
                                'shape': 'star',
                                "text-wrap": "wrap",
                                "text-max-width": 80
                            }
                        }

          elements = [{'data':{'id':'your_id', 'label':'your_label', 'type':'your_type'}]

redpajama_set_name: RedPajamaStackExchange


text:
Q: How to change font-family of drop down's list item? I have a drop-down that lists font families. Like Tahoma, Arial, Verdana, etc. I want to change the font-family of each drop-down item according to the value it represents. Just like Photoshop does it.
I changed the CSS for each drop-down item but it only works on FireFox. It doesn't work on any other browser.
I don't want to use any jQuery plugin.

A: You can do something like this
<select>
<optgroup style="font-family:arial">
    <option>Arial</option>
</optgroup>
<optgroup style="font-family:verdana">
    <option>veranda</option>
</optgroup>

A: You can set fonts for an HTML drop-down in the following way:
1. Build your list of options that will be displayed in your dropdown, but don't apply any styling/classes to any of those options.  In PHP I would store my list of options to a variable and then use that variable to add options to my dropdown which I'll show below.
2. When you want to actually insert the dropdown into the page, use the SELECT tag and put some CSS styling inside that tag as I've shown below:
<SELECT style='font-size: 10px; font-family: "Verdana", Sans-Serif;' name='???????'>
<?php echo $your_variable_containing_dropdown_content; ?>
</SELECT>

That works 100% fine for me on the website I'm currently working. This is just the styling that I've used in my page, but it can be whatever you need it to be.

A: I know this is an old question, but I have found a simpler solution that seems to work in most browsers, if not all (tested in FireFox, Chrome and Edge).
To change the style of each individual item in a select, I simply added a style attribute to the option tags.
Here is an example:

<select>
    <option style="font-family:Arial;background-color:#F22">Arial</option>
    <option style="font-family:'Arial Black'">Arial Black</option>
    <option style="font-family:Verdana">Verdana</option>
</select>

A: That's because the select elements children (options) aren't really stylable and firefox seems to be the only browser to ignore that part of the spec.
The workaround is to replace your select element with a custom widget that uses only stylable elements and perhaps a little javascript for the interactivity. like what's done here: http://jsfiddle.net/sidonaldson/jL7uU/ or http://jsfiddle.net/theredhead/4PQzp/

A: What you can do in CSS is what you described: setting font-family on option elements, and this has limited browser support. Browsers may implement select elements using routines that are partly or completely immune to CSS.
The workaround is to use something else than a select element, such as a set of radio buttons, but it will of course be rendered differently from a dropdown menu. Then you can use e.g.

<input type="radio" name="font" value="Tahoma" id="tahoma">
Tahoma

...

A: I am not the most CSS wise guy around, but it seems to me that if styling the select element changes the font, as many other answers submit, then a CSS rule referring to selects should work, too.
In my case I set the font-family on html and it applied everywhere except select elements. So I changed the rule to apply to html and select elements and it worked. Tested on Chrome and Edge (although Edge didn't need the select rule to begin with).
Bottom line: html, select { font-family: Verdana, Geneva, sans-serif; }

A: This should Give you an Idea as to ho to accomplish this:
<select>

    <option value="Arial">First</option>
    <option value="Verdana">Second</option>

    </select>

    $(function() {
    $('select > option').hover(function() {
        $(this).parent().css({fontFamily:$(this).val()})
})
})

JSFIDDLE

A: Try this:

    <title></title>

      <select>
        <option selected="selected" >One</option>
        <option >Two</option>
      </select>


text:
// Copyright 2014 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License. See the AUTHORS file
// for names of contributors.
//
// Author: Spencer Kimball (spencer.kimball@gmail.com)
// Author: Jiang-Ming Yang (jiangming.yang@gmail.com)
// Author: Tobias Schottdorf (tobias.schottdorf@gmail.com)
// Author: Bram Gruneir (bram+code@cockroachlabs.com)

package storage

import (
	"bytes"
	"crypto/sha256"
	"encoding/gob"
	"fmt"
	"math/rand"
	"reflect"
	"sync"
	"sync/atomic"
	"time"
	"unsafe"

	"github.com/cockroachdb/cockroach/client"
	"github.com/cockroachdb/cockroach/gossip"
	"github.com/cockroachdb/cockroach/keys"
	"github.com/cockroachdb/cockroach/multiraft"
	"github.com/cockroachdb/cockroach/proto"
	"github.com/cockroachdb/cockroach/storage/engine"
	"github.com/cockroachdb/cockroach/util"
	"github.com/cockroachdb/cockroach/util/hlc"
	"github.com/cockroachdb/cockroach/util/log"
	gogoproto "github.com/gogo/protobuf/proto"
	"golang.org/x/net/context"
)

// init pre-registers RangeDescriptor, PrefixConfigMap types and Transaction.
func init() {
	gob.Register(proto.StoreDescriptor{})
	gob.Register(PrefixConfigMap{})
	gob.Register(&proto.AcctConfig{})
	gob.Register(&proto.PermConfig{})
	gob.Register(&proto.ZoneConfig{})
	gob.Register(proto.RangeDescriptor{})
	gob.Register(proto.Transaction{})
}

var (
	// DefaultHeartbeatInterval is how often heartbeats are sent from the
	// transaction coordinator to a live transaction. These keep it from
	// being preempted by other transactions writing the same keys. If a
	// transaction fails to be heartbeat within 2x the heartbeat interval,
	// it may be aborted by conflicting txns.
	DefaultHeartbeatInterval = 5 * time.Second

	// clusterIDGossipTTL is time-to-live for cluster ID. The cluster ID
	// serves as the sentinel gossip key which informs a node whether or
	// not it's connected to the primary gossip network and not just a
	// partition. As such it must expire on a reasonable basis and be
	// continually re-gossiped. The replica which is the raft leader of
	// the first range gossips it.
	clusterIDGossipTTL = 2 * time.Minute
	// clusterIDGossipInterval is the approximate interval at which the
	// sentinel info is gossiped.
	clusterIDGossipInterval = clusterIDGossipTTL / 2

	// configGossipTTL is the time-to-live for configuration maps.
	configGossipTTL = 0 * time.Second // does not expire
	// configGossipInterval is the interval at which range leaders gossip
	// their config maps. Even if config maps do not expire, we still
	// need a periodic gossip to safeguard against failure of a leader
	// to gossip after performing an update to the map.
	configGossipInterval = 1 * time.Minute
)

// TestingCommandFilter may be set in tests to intercept the handling
// of commands and artificially generate errors. Return true to
// terminate processing with the filled-in response, or false to
// continue with regular processing. Note that in a multi-replica test
// this filter will be run once for each replica and must produce
// consistent results each time. Should only be used in tests in the
// storage package but needs to be exported due to circular import
// issues.
var TestingCommandFilter func(proto.Request, proto.Response) bool

// raftInitialLogIndex is the starting point for the raft log. We bootstrap
// the raft membership by synthesizing a snapshot as if there were some
// discarded prefix to the log, so we must begin the log at an arbitrary
// index greater than 1.
const (
	raftInitialLogIndex = 10
	raftInitialLogTerm  = 5

	// DefaultLeaderLeaseDuration is the default duration of the leader lease.
	DefaultLeaderLeaseDuration = time.Second
)

// configDescriptor describes administrative configuration maps
// affecting ranges of the key-value map by key prefix.
type configDescriptor struct {
	keyPrefix proto.Key   // Range key prefix
	gossipKey string      // Gossip key
	configI   interface{} // Config struct interface
}

// configDescriptors is an array containing the accounting, permissions
// and zone configuration descriptors.
var configDescriptors = [...]*configDescriptor{
	{keys.ConfigAccountingPrefix, gossip.KeyConfigAccounting, proto.AcctConfig{}},
	{keys.ConfigPermissionPrefix, gossip.KeyConfigPermission, proto.PermConfig{}},
	{keys.ConfigZonePrefix, gossip.KeyConfigZone, proto.ZoneConfig{}},
}

// tsCacheMethods specifies the set of methods which affect the
// timestamp cache.
var tsCacheMethods = [...]bool{
	proto.Get:                        true,
	proto.Put:                        true,
	proto.ConditionalPut:             true,
	proto.Increment:                  true,
	proto.Scan:                       true,
	proto.Delete:                     true,
	proto.DeleteRange:                true,
	proto.InternalResolveIntent:      true,
	proto.InternalResolveIntentRange: true,
}

// usesTimestampCache returns true if the request affects or is
// affected by the timestamp cache.
func usesTimestampCache(r proto.Request) bool {
	m := r.Method()
	if m < 0 || m >= proto.Method(len(tsCacheMethods)) {
		return false
	}
	return tsCacheMethods[m]
}

// A pendingCmd holds the reply buffer and a done channel for a command
// sent to Raft. Once committed to the Raft log, the command is
// executed and the result returned via the done channel.
type pendingCmd struct {
	Reply proto.Response
	done  chan error // Used to signal waiting RPC handler
}

// A rangeManager is an interface satisfied by Store through which ranges
// contained in the store can access the methods required for splitting.
type rangeManager interface {
	// Accessors for shared state.
	ClusterID() string
	StoreID() proto.StoreID
	RaftNodeID() proto.RaftNodeID
	Clock() *hlc.Clock
	Engine() engine.Engine
	DB() *client.DB
	allocator() *allocator
	Gossip() *gossip.Gossip
	splitQueue() *splitQueue
	Stopper() *util.Stopper
	EventFeed() StoreEventFeed
	Context(context.Context) context.Context

	// Range manipulation methods.
	LookupRange(start, end proto.Key) *Range
	MergeRange(subsumingRng *Range, updatedEndKey proto.Key, subsumedRaftID int64) error
	NewRangeDescriptor(start, end proto.Key, replicas []proto.Replica) (*proto.RangeDescriptor, error)
	NewSnapshot() engine.Engine
	ProposeRaftCommand(cmdIDKey, proto.InternalRaftCommand) <-chan error
	RemoveRange(rng *Range) error
	SplitRange(origRng, newRng *Range) error
	processRangeDescriptorUpdate(rng *Range) error
}

// A Range is a contiguous keyspace with writes managed via an
// instance of the Raft consensus algorithm. Many ranges may exist
// in a store and they are unlikely to be contiguous. Ranges are
// independent units and are responsible for maintaining their own
// integrity by replacing failed replicas, splitting and merging
// as appropriate.
type Range struct {
	desc     unsafe.Pointer // Atomic pointer for *proto.RangeDescriptor
	rm       rangeManager   // Makes some store methods available
	stats    *rangeStats    // Range statistics
	maxBytes int64          // Max bytes before split.
	// Held while a split, merge, or replica change is underway.
	metaLock sync.Mutex // TODO(bdarnell): Revisit the metaLock.
	// Last index persisted to the raft log (not necessarily committed).
	// Updated atomically.
	lastIndex uint64
	// Last index applied to the state machine. Updated atomically.
	appliedIndex uint64
	configHashes map[int][]byte // Config map sha256 hashes @ last gossip
	lease        unsafe.Pointer // Information for leader lease, updated atomically
	llMu         sync.Mutex     // Synchronizes readers' requests for leader lease

	sync.RWMutex                 // Protects the following fields:
	cmdQ         *CommandQueue   // Enforce at most one command is running per key(s)
	tsCache      *TimestampCache // Most recent timestamps for keys / key ranges
	respCache    *ResponseCache  // Provides idempotence for retries
	pendingCmds  map[cmdIDKey]*pendingCmd
}

// NewRange initializes the range using the given metadata.
func NewRange(desc *proto.RangeDescriptor, rm rangeManager) (*Range, error) {
	r := &Range{
		rm:          rm,
		cmdQ:        NewCommandQueue(),
		tsCache:     NewTimestampCache(rm.Clock()),
		respCache:   NewResponseCache(desc.RaftID, rm.Engine()),
		pendingCmds: map[cmdIDKey]*pendingCmd{},
	}
	// Do not call setDesc to avoid calling processRangeDescriptorUpdate().
	atomic.StorePointer(&r.desc, unsafe.Pointer(desc))

	lastIndex, err := r.loadLastIndex()
	if err != nil {
		return nil, err
	}
	atomic.StoreUint64(&r.lastIndex, lastIndex)

	appliedIndex, err := r.loadAppliedIndex(r.rm.Engine())
	if err != nil {
		return nil, err
	}
	atomic.StoreUint64(&r.appliedIndex, appliedIndex)

	lease, err := loadLeaderLease(r.rm.Engine(), desc.RaftID)
	if err != nil {
		return nil, err
	}
	atomic.StorePointer(&r.lease, unsafe.Pointer(lease))

	if r.stats, err = newRangeStats(desc.RaftID, rm.Engine()); err != nil {
		return nil, err
	}

	return r, nil
}

// String returns a string representation of the range.
func (r *Range) String() string {
	return fmt.Sprintf("range=%d [%s - %s)", r.Desc().RaftID, r.Desc().StartKey, r.Desc().EndKey)
}

// Destroy cleans up all data associated with this range.
func (r *Range) Destroy() error {
	iter := newRangeDataIterator(r.Desc(), r.rm.Engine())
	defer iter.Close()
	batch := r.rm.Engine().NewBatch()
	defer batch.Close()
	for ; iter.Valid(); iter.Next() {
		_ = batch.Clear(iter.Key())
	}
	return batch.Commit()
}

// context returns a context which is initialized with information about
// this range. It is only relevant when commands need to be executed
// on this range in the absence of a pre-existing context, such as
// during range scanner operations.
func (r *Range) context() context.Context {
	return context.WithValue(r.rm.Context(nil), log.RaftID, r.Desc().RaftID)
}

// GetMaxBytes atomically gets the range maximum byte limit.
func (r *Range) GetMaxBytes() int64 {
	return atomic.LoadInt64(&r.maxBytes)
}

// SetMaxBytes atomically sets the maximum byte limit before
// split. This value is cached by the range for efficiency.
func (r *Range) SetMaxBytes(maxBytes int64) {
	atomic.StoreInt64(&r.maxBytes, maxBytes)
}

// IsFirstRange returns true if this is the first range.
func (r *Range) IsFirstRange() bool {
	return bytes.Equal(r.Desc().StartKey, proto.KeyMin)
}

func loadLeaderLease(eng engine.Engine, raftID int64) (*proto.Lease, error) {
	lease := &proto.Lease{}
	if _, err := engine.MVCCGetProto(eng, keys.RaftLeaderLeaseKey(raftID), proto.ZeroTimestamp, true, nil, lease); err != nil {
		return nil, err
	}
	return lease, nil
}

// getLease returns the current leader lease.
func (r *Range) getLease() *proto.Lease {
	return (*proto.Lease)(atomic.LoadPointer(&r.lease))
}

// newNotLeaderError returns a NotLeaderError intialized with the
// replica for the last known holder of the leader lease.
func (r *Range) newNotLeaderError() error {
	err := &proto.NotLeaderError{}
	if l := r.getLease(); l.RaftNodeID != 0 {
		_, err.Replica = r.Desc().FindReplica(r.rm.StoreID())
		_, storeID := proto.DecodeRaftNodeID(proto.RaftNodeID(l.RaftNodeID))
		_, err.Leader = r.Desc().FindReplica(storeID)
	}
	return err
}

// requestLeaderLease sends a request to obtain or extend a leader lease for
// this replica. Unless an error is returned, the obtained lease will be valid
// for a time interval containing the requested timestamp.
func (r *Range) requestLeaderLease(timestamp proto.Timestamp) error {
	// TODO(Tobias): get duration from configuration, either as a config flag
	// or, later, dynamically adjusted.
	duration := int64(DefaultLeaderLeaseDuration)
	// Prepare a Raft command to get a leader lease for this replica.
	expiration := timestamp.Add(duration, 0)
	args := &proto.InternalLeaderLeaseRequest{
		RequestHeader: proto.RequestHeader{
			Key:       r.Desc().StartKey,
			Timestamp: timestamp,
			CmdID: proto.ClientCmdID{
				WallTime: r.rm.Clock().Now().WallTime,
				Random:   rand.Int63(),
			},
		},
		Lease: proto.Lease{
			Start:      timestamp,
			Expiration: expiration,
			RaftNodeID: uint64(r.rm.RaftNodeID()),
		},
	}
	// Send lease request directly to raft in order to skip unnecessary
	// checks from normal request machinery, (e.g. the command queue).
	errChan, pendingCmd := r.proposeRaftCommand(args, &proto.InternalLeaderLeaseResponse{})
	var err error
	if err = <-errChan; err == nil {
		// Next if the command was committed, wait for the range to apply it.
		err = <-pendingCmd.done
	}
	return err
}

// redirectOnOrAcquireLeaderLease checks whether this replica has the
// leader lease at the specified timestamp. If it does, returns
// success. If another replica currently holds the lease, redirects by
// returning NotLeaderError. If the lease is expired, a renewal is
// synchronously requested. This method uses the leader lease mutex
// to guarantee only one request to grant the lease is pending.
//
// TODO(spencer): implement threshold regrants to avoid latency in
//  the presence of read or write pressure sufficiently close to the
//  current lease's expiration.
//
// TODO(spencer): for write commands, don't wait while requesting
//  the leader lease. If the lease acquisition fails, the write cmd
//  will fail as well. If it succeeds, as is likely, then the write
//  will not incur latency waiting for the command to complete.
//  Reads, however, must wait.
func (r *Range) redirectOnOrAcquireLeaderLease(timestamp proto.Timestamp) error {
	r.llMu.Lock()
	defer r.llMu.Unlock()
	// If lease is currently held by another, redirect to holder.
	if held, expired := r.HasLeaderLease(timestamp); !held && !expired {
		return r.newNotLeaderError()
	} else if !held || expired {
		// Otherwise, if not held by this replica or expired, request renewal.
		err := r.requestLeaderLease(timestamp)
		// Getting a LeaseRejectedError back means someone else got there
		// first.
		if _, ok := err.(*proto.LeaseRejectedError); ok {
			if held, expired := r.HasLeaderLease(timestamp); !held && !expired {
				return r.newNotLeaderError()
			}
		}
		return err
	}
	return nil
}

// verifyLeaderLease checks whether the requesting replica (by raft
// node ID) holds the leader lease covering the specified timestamp.
func (r *Range) verifyLeaderLease(originRaftNodeID proto.RaftNodeID, timestamp proto.Timestamp) bool {
	l := r.getLease()
	return uint64(originRaftNodeID) == l.RaftNodeID && timestamp.Less(l.Expiration)
}

// HasLeaderLease returns whether this replica holds or was the last
// holder of the leader lease, and whether the lease has expired.
// Leases may not overlap, and a gap between successive lease holders
// is expected.
func (r *Range) HasLeaderLease(timestamp proto.Timestamp) (bool, bool) {
	if l := r.getLease(); l.RaftNodeID != 0 {
		held := l.RaftNodeID == uint64(r.rm.RaftNodeID())
		expired := !timestamp.Less(l.Expiration)
		return held, expired
	}
	// The lease has never been held.
	return false, true
}

// WaitForLeaderLease is used from unittests to wait until this range
// has the leader lease.
func (r *Range) WaitForLeaderLease(t util.Tester) {
	util.SucceedsWithin(t, 1*time.Second, func() error {
		return r.requestLeaderLease(r.rm.Clock().Now())
	})
}

// isInitialized is true if we know the metadata of this range, either
// because we created it or we have received an initial snapshot from
// another node. It is false when a range has been created in response
// to an incoming message but we are waiting for our initial snapshot.
func (r *Range) isInitialized() bool {
	return len(r.Desc().EndKey) > 0
}

// Desc atomically returns the range's descriptor.
func (r *Range) Desc() *proto.RangeDescriptor {
	return (*proto.RangeDescriptor)(atomic.LoadPointer(&r.desc))
}

// setDesc atomically sets the range's descriptor. This method calls
// processRangeDescriptorUpdate() to make the range manager handle the
// descriptor update.
func (r *Range) setDesc(desc *proto.RangeDescriptor) error {
	atomic.StorePointer(&r.desc, unsafe.Pointer(desc))
	if r.rm == nil {
		// r.rm is null in some tests.
		return nil
	}
	return r.rm.processRangeDescriptorUpdate(r)
}

// GetReplica returns the replica for this range from the range descriptor.
// Returns nil if the replica is not found.
func (r *Range) GetReplica() *proto.Replica {
	_, replica := r.Desc().FindReplica(r.rm.StoreID())
	return replica
}

// GetMVCCStats returns a copy of the MVCC stats object for this range.
func (r *Range) GetMVCCStats() proto.MVCCStats {
	return r.stats.GetMVCC()
}

// ContainsKey returns whether this range contains the specified key.
func (r *Range) ContainsKey(key proto.Key) bool {
	return r.Desc().ContainsKey(keys.KeyAddress(key))
}

// ContainsKeyRange returns whether this range contains the specified
// key range from start to end.
func (r *Range) ContainsKeyRange(start, end proto.Key) bool {
	return r.Desc().ContainsKeyRange(keys.KeyAddress(start), keys.KeyAddress(end))
}

// GetGCMetadata reads the latest GC metadata for this range.
func (r *Range) GetGCMetadata() (*proto.GCMetadata, error) {
	key := keys.RangeGCMetadataKey(r.Desc().RaftID)
	gcMeta := &proto.GCMetadata{}
	_, err := engine.MVCCGetProto(r.rm.Engine(), key, proto.ZeroTimestamp, true, nil, gcMeta)
	if err != nil {
		return nil, err
	}
	return gcMeta, nil
}

// GetLastVerificationTimestamp reads the timestamp at which the range's
// data was last verified.
func (r *Range) GetLastVerificationTimestamp() (proto.Timestamp, error) {
	key := keys.RangeLastVerificationTimestampKey(r.Desc().RaftID)
	timestamp := proto.Timestamp{}
	_, err := engine.MVCCGetProto(r.rm.Engine(), key, proto.ZeroTimestamp, true, nil, &timestamp)
	if err != nil {
		return proto.ZeroTimestamp, err
	}
	return timestamp, nil
}

// SetLastVerificationTimestamp writes the timestamp at which the range's
// data was last verified.
func (r *Range) SetLastVerificationTimestamp(timestamp proto.Timestamp) error {
	key := keys.RangeLastVerificationTimestampKey(r.Desc().RaftID)
	return engine.MVCCPutProto(r.rm.Engine(), nil, key, proto.ZeroTimestamp, nil, &timestamp)
}

// AddCmd adds a command for execution on this range. The command's
// affected keys are verified to be contained within the range and the
// range's leadership is confirmed. The command is then dispatched
// either along the read-only execution path or the read-write Raft
// command queue. If wait is false, read-write commands are added to
// Raft without waiting for their completion.
func (r *Range) AddCmd(ctx context.Context, call client.Call, wait bool) error {
	args, reply := call.Args, call.Reply
	header := args.Header()
	if !r.ContainsKeyRange(header.Key, header.EndKey) {
		err := proto.NewRangeKeyMismatchError(header.Key, header.EndKey, r.Desc())
		reply.Header().SetGoError(err)
		return err
	}

	// Differentiate between admin, read-only and read-write.
	if proto.IsAdmin(args) {
		return r.addAdminCmd(ctx, args, reply)
	} else if proto.IsReadOnly(args) {
		return r.addReadOnlyCmd(ctx, args, reply)
	}
	return r.addWriteCmd(ctx, args, reply, wait)
}

// beginCmd waits for any overlapping, already-executing commands via
// the command queue and adds itself to the queue to gate follow-on
// commands which overlap its key range. This method will block if
// there are any overlapping commands already in the queue. Returns
// the command queue insertion key, to be supplied to subsequent
// invocation of endCmd().
func (r *Range) beginCmd(header *proto.RequestHeader, readOnly bool) interface{} {
	r.Lock()
	var wg sync.WaitGroup
	r.cmdQ.GetWait(header.Key, header.EndKey, readOnly, &wg)
	cmdKey := r.cmdQ.Add(header.Key, header.EndKey, readOnly)
	r.Unlock()
	wg.Wait()
	// Update the incoming timestamp if unset. Wait until after any
	// preceding command(s) for key range are complete so that the node
	// clock has been updated to the high water mark of any commands
	// which might overlap this one in effect.
	if header.Timestamp.Equal(proto.ZeroTimestamp) {
		header.Timestamp = r.rm.Clock().Now()
	}
	return cmdKey
}

// endCmd removes a pending command from the command queue.
func (r *Range) endCmd(cmdKey interface{}, args proto.Request, err error, readOnly bool) {
	r.Lock()
	if err == nil && usesTimestampCache(args) {
		header := args.Header()
		r.tsCache.Add(header.Key, header.EndKey, header.Timestamp, header.Txn.GetID(), readOnly)
	}
	r.cmdQ.Remove(cmdKey)
	r.Unlock()
}

// addAdminCmd executes the command directly. There is no interaction
// with the command queue or the timestamp cache, as admin commands
// are not meant to consistently access or modify the underlying data.
// Admin commands must run on the leader replica.
func (r *Range) addAdminCmd(ctx context.Context, args proto.Request, reply proto.Response) error {
	// Admin commands always require the leader lease.
	if err := r.redirectOnOrAcquireLeaderLease(args.Header().Timestamp); err != nil {
		reply.Header().SetGoError(err)
		return err
	}

	switch args.(type) {
	case *proto.AdminSplitRequest:
		r.AdminSplit(args.(*proto.AdminSplitRequest), reply.(*proto.AdminSplitResponse))
	case *proto.AdminMergeRequest:
		r.AdminMerge(args.(*proto.AdminMergeRequest), reply.(*proto.AdminMergeResponse))
	default:
		return util.Error("unrecognized admin command")
	}
	return reply.Header().GoError()
}

// addReadOnlyCmd updates the read timestamp cache and waits for any
// overlapping writes currently processing through Raft ahead of us to
// clear via the read queue.
func (r *Range) addReadOnlyCmd(ctx context.Context, args proto.Request, reply proto.Response) error {
	header := args.Header()

	// If read-consistency is set to INCONSISTENT, run directly.
	if header.ReadConsistency == proto.INCONSISTENT {
		// But disallow any inconsistent reads within txns.
		if header.Txn != nil {
			reply.Header().SetGoError(util.Error("cannot allow inconsistent reads within a transaction"))
			return reply.Header().GoError()
		}
		if header.Timestamp.Equal(proto.ZeroTimestamp) {
			header.Timestamp = r.rm.Clock().Now()
		}
		return r.executeCmd(r.rm.Engine(), nil, args, reply)
	} else if header.ReadConsistency == proto.CONSENSUS {
		reply.Header().SetGoError(util.Error("consensus reads not implemented"))
		return reply.Header().GoError()
	}

	// Add the read to the command queue to gate subsequent
	// overlapping commands until this command completes.
	cmdKey := r.beginCmd(header, true)

	// This replica must have leader lease to process a consistent read.
	if err := r.redirectOnOrAcquireLeaderLease(args.Header().Timestamp); err != nil {
		r.endCmd(cmdKey, args, err, true /* readOnly */)
		reply.Header().SetGoError(err)
		return err
	}

	// Execute read-only command.
	err := r.executeCmd(r.rm.Engine(), nil, args, reply)

	// Only update the timestamp cache if the command succeeded.
	r.endCmd(cmdKey, args, err, true /* readOnly */)

	return err
}

// addWriteCmd first consults the response cache to determine whether
// this command has already been sent to the range. If a response is
// found, it's returned immediately and not submitted to raft. Next,
// the timestamp cache is checked to determine if any newer accesses to
// this command's affected keys have been made. If so, this command's
// timestamp is moved forward. Finally the keys affected by this
// command are added as pending writes to the read queue and the
// command is submitted to Raft. Upon completion, the write is removed
// from the read queue and the reply is added to the response cache.
// If wait is true, will block until the command is complete.
func (r *Range) addWriteCmd(ctx context.Context, args proto.Request, reply proto.Response, wait bool) error {
	// Check the response cache in case this is a replay. This call
	// may block if the same command is already underway.
	header := args.Header()

	// Add the write to the command queue to gate subsequent overlapping
	// Commands until this command completes. Note that this must be
	// done before getting the max timestamp for the key(s), as
	// timestamp cache is only updated after preceding commands have
	// been run to successful completion.
	cmdKey := r.beginCmd(header, false)

	// This replica must have leader lease to process a write.
	if err := r.redirectOnOrAcquireLeaderLease(header.Timestamp); err != nil {
		r.endCmd(cmdKey, args, err, false /* !readOnly */)
		reply.Header().SetGoError(err)
		return err
	}

	// Two important invariants of Cockroach: 1) encountering a more
	// recently written value means transaction restart. 2) values must
	// be written with a greater timestamp than the most recent read to
	// the same key. Check the timestamp cache for reads/writes which
	// are at least as recent as the timestamp of this write. For
	// writes, send WriteTooOldError; for reads, update the write's
	// timestamp. When the write returns, the updated timestamp will
	// inform the final commit timestamp.
	if usesTimestampCache(args) {
		r.Lock()
		rTS, wTS := r.tsCache.GetMax(header.Key, header.EndKey, header.Txn.GetID())
		r.Unlock()

		// Always push the timestamp forward if there's been a read which
		// occurred after our txn timestamp.
		if !rTS.Less(header.Timestamp) {
			header.Timestamp = rTS.Next()
		}
		// If there's a newer write timestamp...
		if !wTS.Less(header.Timestamp) {
			// If we're in a txn, set a write too old error in reply. We
			// still go ahead and try the write because we want to avoid
			// restarting the transaction in the event that there isn't an
			// intent or the intent can be pushed by us.
			if header.Txn != nil {
				err := &proto.WriteTooOldError{Timestamp: header.Timestamp, ExistingTimestamp: wTS}
				reply.Header().SetGoError(err)
			} else {
				// Otherwise, make sure we advance the request's timestamp.
				header.Timestamp = wTS.Next()
			}
		}
	}

	errChan, pendingCmd := r.proposeRaftCommand(args, reply)

	// Create a completion func for mandatory cleanups which we either
	// run synchronously if we're waiting or in a goroutine otherwise.
	completionFunc := func() error {
		// First wait for raft to commit or abort the command.
		var err error
		if err = <-errChan; err == nil {
			// Next if the command was committed, wait for the range to apply it.
			err = <-pendingCmd.done
		} else if err == multiraft.ErrGroupDeleted {
			// This error needs to be converted appropriately so that
			// clients will retry.
			err = proto.NewRangeNotFoundError(r.Desc().RaftID)
		}
		// As for reads, update timestamp cache with the timestamp
		// of this write on success. This ensures a strictly higher
		// timestamp for successive writes to the same key or key range.
		r.endCmd(cmdKey, args, err, false /* !readOnly */)
		return err
	}

	if wait {
		return completionFunc()
	}
	go func() {
		// If the original client didn't wait (e.g. resolve write intent),
		// log execution errors so they're surfaced somewhere.
		if err := completionFunc(); err != nil {
			// TODO(tschottdorf): possible security risk to log args.
			log.Warningc(ctx, "async execution of %v failed: %s", args, err)
		}
	}()
	return nil
}

// proposeRaftCommand prepares necessary pending command struct and
// initializes a client command ID if one hasn't been. It then
// proposes the command to Raft and returns the error channel and
// pending command struct for receiving.
func (r *Range) proposeRaftCommand(args proto.Request, reply proto.Response) (<-chan error, *pendingCmd) {
	pendingCmd := &pendingCmd{
		Reply: reply,
		done:  make(chan error, 1),
	}
	raftCmd := proto.InternalRaftCommand{
		RaftID:       r.Desc().RaftID,
		OriginNodeID: uint64(r.rm.RaftNodeID()),
	}
	cmdID := args.Header().GetOrCreateCmdID(r.rm.Clock().PhysicalNow())
	ok := raftCmd.Cmd.SetValue(args)
	if !ok {
		log.Fatalf("unknown command type %T", args)
	}
	idKey := makeCmdIDKey(cmdID)
	r.Lock()
	r.pendingCmds[idKey] = pendingCmd
	r.Unlock()
	errChan := r.rm.ProposeRaftCommand(idKey, raftCmd)

	return errChan, pendingCmd
}

// processRaftCommand processes a raft command by unpacking the command
// struct to get args and reply and then applying the command to the
// state machine via applyRaftCommand(). The error result is sent on
// the command's done channel, if available.
//
// TODO(spencer): Differentiate between errors caused by the normal culprits --
// bad inputs from clients, stale information, etc. and errors which might
// cause the range replicas to diverge -- running out of disk space, underlying
// rocksdb corruption, etc. Do a careful code audit to make sure we identify
// errors which should be classified as a ReplicaCorruptionError--when those
// bubble up to the point where we've just tried to execute a Raft command, the
// Raft replica would need to stall itself.
func (r *Range) processRaftCommand(idKey cmdIDKey, index uint64, raftCmd proto.InternalRaftCommand) error {
	if index == 0 {
		log.Fatal("processRaftCommand requires a non-zero index")
	}
	r.Lock()
	cmd := r.pendingCmds[idKey]
	delete(r.pendingCmds, idKey)
	r.Unlock()

	args := raftCmd.Cmd.GetValue().(proto.Request)
	var reply proto.Response
	if cmd != nil {
		// We initiated this command, so use the caller-supplied reply.
		reply = cmd.Reply
	} else {
		// This command originated elsewhere so we must create a new reply buffer.
		reply = args.CreateReply()
	}

	err := r.applyRaftCommand(index, proto.RaftNodeID(raftCmd.OriginNodeID), args, reply)

	if cmd != nil {
		cmd.done <- err
	} else if err != nil {
		if log.V(1) {
			log.Errorf("error executing raft command %s: %s", args.Method(), err)
		}
	}
	return err
}

// applyRaftCommand applies a raft command from the replicated log to
// the underlying state machine (i.e. the engine).
// The caller needs to hold the range lock.
func (r *Range) applyRaftCommand(index uint64, originNodeID proto.RaftNodeID, args proto.Request, reply proto.Response) error {
	if index <= 0 {
		log.Fatalf("raft command index is <= 0")
	}

	committed := false
	defer func() {
		if !committed {
			// We didn't commit the batch, but advance the last applied index nonetheless.
			if err := setAppliedIndex(r.rm.Engine(), r.Desc().RaftID, index); err != nil {
				log.Fatalf("could not advance applied index: %s", err)
			}
			atomic.StoreUint64(&r.appliedIndex, index)
		}
	}()

	header := args.Header()

	// Check the response cache to ensure idempotency.
	if proto.IsWrite(args) {
		if ok, err := r.respCache.GetResponse(header.CmdID, reply); ok && err == nil {
			if log.V(1) {
				log.Infof("found response cache entry for %+v", args.Header().CmdID)
			}
			return reply.Header().GoError()
		} else if ok && err != nil {
			newErr := util.Errorf("unable to read result for %+v from the response cache: %s", args, err)
			reply.Header().SetGoError(newErr)
			return newErr
		}
	}

	// Verify the leader lease is held; Note that we don't require the
	// leader lease when trying to grant the leader lease!
	if _, ok := args.(*proto.InternalLeaderLeaseRequest); !ok {
		if !r.verifyLeaderLease(originNodeID, header.Timestamp) {
			err := r.newNotLeaderError()
			reply.Header().SetGoError(err)
			return err
		}
	}

	// Create a new batch for the command to ensure all or nothing semantics.
	batch := r.rm.Engine().NewBatch()
	defer batch.Close()

	// Create a proto.MVCCStats instance.
	ms := proto.MVCCStats{}

	// Execute the command; the error will also be set in the reply header.
	err := r.executeCmd(batch, &ms, args, reply)

	if oldIndex := atomic.LoadUint64(&r.appliedIndex); oldIndex >= index {
		log.Fatalf("applied index moved backwards: %d >= %d", oldIndex, index)
	}

	// Advance the applied index atomically within the batch.
	if e := setAppliedIndex(batch, r.Desc().RaftID, index); e != nil {
		if reply.Header().GoError() == nil {
			reply.Header().SetGoError(e)
		}
		err = e
	}

	if err == nil && proto.IsWrite(args) {
		// On success, flush the MVCC stats to the batch and commit.
		if err := r.stats.MergeMVCCStats(batch, &ms, header.Timestamp.WallTime); err != nil {
			log.Fatal(err) // should never fail writing to a batch
		}
		if err := batch.Commit(); err != nil {
			log.Fatalf("failed to commit batch from Raft command execution: %s", err)
		}
		committed = true
		// Publish update to event feed.
		r.rm.EventFeed().updateRange(r, args.Method(), &ms)
		// After successful commit, update cached stats and appliedIndex value.
		atomic.StoreUint64(&r.appliedIndex, index)
		// If the commit succeeded, potentially add range to split queue.
		r.maybeAddToSplitQueue()
		// Maybe update gossip configs on a put.
		switch args.(type) {
		case *proto.PutRequest, *proto.DeleteRequest, *proto.DeleteRangeRequest:
			if header.Key.Less(keys.SystemMax) {
				// We hold the lock already.
				r.maybeGossipConfigsLocked(func(configPrefix proto.Key) bool {
					return bytes.HasPrefix(header.Key, configPrefix)
				})
			}
		}
	}

	// Add this command's result to the response cache if this is a
	// write method. This must be done as part of the execution of
	// raft commands so that every replica maintains the same responses
	// to continue request idempotence when leadership changes.
	if proto.IsWrite(args) {
		if putErr := r.respCache.PutResponse(args.Header().CmdID, reply); putErr != nil {
			log.Errorf("unable to write result of %+v: %+v to the response cache: %s",
				args, reply, putErr)
		}
	}

	return reply.Header().GoError()
}

// getLeaseForGossip tries to obtain a leader lease. Only one of the replicas
// should gossip; the bool returned indicates whether it's us.
func (r *Range) getLeaseForGossip(ctx context.Context) (bool, error) {
	// If no Gossip available (some tests) or range too fresh, noop.
	if r.rm.Gossip() == nil || !r.isInitialized() {
		return false, util.Errorf("no gossip or range not initialized")
	}
	timestamp := r.rm.Clock().Now()

	// Check for or obtain the lease, if none active.
	err := r.redirectOnOrAcquireLeaderLease(timestamp)
	if err != nil {
		switch e := err.(type) {
		// NotLeaderError means there is an active lease, leaseRejectedError
		// means we tried to get one but someone beat us to it.
		case *proto.NotLeaderError, *proto.LeaseRejectedError:
		default:
			// Any other error is worth being logged visibly.
			log.Warningc(ctx, "could not acquire lease for range gossip: %s", e)
			return false, err
		}
	}
	return err == nil, nil
}

// maybeGossipFirstRange adds the sentinel and first range metadata to gossip
// if this is the first range and a leader lease can be obtained. The Store
// calls this periodically on first range replicas.
func (r *Range) maybeGossipFirstRange() error {
	if !r.IsFirstRange() {
		return nil
	}

	ctx := r.context()

	// Gossip the cluster ID from all replicas of the first range.
	log.Infof("gossiping cluster id %s from store %d, range %d", r.rm.ClusterID(),
		r.rm.StoreID(), r.Desc().RaftID)
	if err := r.rm.Gossip().AddInfo(gossip.KeyClusterID, r.rm.ClusterID(), clusterIDGossipTTL); err != nil {
		log.Errorc(ctx, "failed to gossip cluster ID: %s", err)
	}

	if ok, err := r.getLeaseForGossip(ctx); !ok || err != nil {
		return err
	}
	log.Infof("gossiping sentinel from store %d, range %d", r.rm.StoreID(), r.Desc().RaftID)
	if err := r.rm.Gossip().AddInfo(gossip.KeySentinel, r.rm.ClusterID(), clusterIDGossipTTL); err != nil {
		log.Errorc(ctx, "failed to gossip cluster ID: %s", err)
	}
	log.Infof("gossiping first range from store %d, range %d", r.rm.StoreID(), r.Desc().RaftID)
	if err := r.rm.Gossip().AddInfo(gossip.KeyFirstRangeDescriptor, *r.Desc(), configGossipTTL); err != nil {
		log.Errorc(ctx, "failed to gossip first range metadata: %s", err)
	}
	return nil
}

// maybeGossipConfigs gossips those configuration maps for which the supplied
// function returns true and whose contents are marked dirty. Configuration
// maps include accounting, permissions, and zones. The store is in charge of
// the initial update, and the range itself re-triggers updates following
// writes that may have altered any of the maps.
//
// Note that maybeGossipConfigs does not check the leader lease; it is called
// on only when the lease is actually held.
// TODO(tschottdorf): The main reason this method does not try to get the lease
// is that InternalLeaderLease calls it, which means that we would wind up
// deadlocking in redirectOnOrObtainLeaderLease. Can possibly simplify.
func (r *Range) maybeGossipConfigs(match func(proto.Key) bool) {
	r.Lock()
	defer r.Unlock()
	r.maybeGossipConfigsLocked(match)
}

func (r *Range) maybeGossipConfigsLocked(match func(configPrefix proto.Key) bool) {
	if r.rm.Gossip() == nil || !r.isInitialized() {
		return
	}
	for i, cd := range configDescriptors {
		if match(cd.keyPrefix) {
			// Check for a bad range split. This should never happen as ranges
			// cannot be split mid-config.
			if !r.ContainsKey(cd.keyPrefix.PrefixEnd()) {
				// If we ever implement configs that span multiple ranges,
				// we must update store.startGossip accordingly. For the
				// time being, it will only fire the first range.
				log.Fatalf("range splits configuration values for %s", cd.keyPrefix)
			}
			configMap, hash, err := r.loadConfigMap(cd.keyPrefix, cd.configI)
			if err != nil {
				log.Errorf("failed loading %s config map: %s", cd.gossipKey, err)
				continue
			}
			if r.configHashes == nil {
				r.configHashes = map[int][]byte{}
			}
			if prevHash, ok := r.configHashes[i]; !ok || !bytes.Equal(prevHash, hash) {
				r.configHashes[i] = hash
				log.Infof("gossiping %s config from store %d, range %d", cd.gossipKey, r.rm.StoreID(), r.Desc().RaftID)
				if err := r.rm.Gossip().AddInfo(cd.gossipKey, configMap, 0*time.Second); err != nil {
					log.Errorf("failed to gossip %s configMap: %s", cd.gossipKey, err)
					continue
				}
			}
		}
	}
}

// loadConfigMap scans the config entries under keyPrefix and
// instantiates/returns a config map and its sha256 hash. Prefix
// configuration maps include accounting, permissions, and zones.
func (r *Range) loadConfigMap(keyPrefix proto.Key, configI interface{}) (PrefixConfigMap, []byte, error) {
	kvs, err := engine.MVCCScan(r.rm.Engine(), keyPrefix, keyPrefix.PrefixEnd(), 0, proto.MaxTimestamp, true, nil)
	if err != nil {
		return nil, nil, err
	}
	var configs []*PrefixConfig
	sha := sha256.New()
	for _, kv := range kvs {
		// Instantiate an instance of the config type by unmarshalling
		// proto encoded config from the Value into a new instance of configI.
		config := reflect.New(reflect.TypeOf(configI)).Interface().(gogoproto.Message)
		if err := gogoproto.Unmarshal(kv.Value.Bytes, config); err != nil {
			return nil, nil, util.Errorf("unable to unmarshal config key %s: %s", string(kv.Key), err)
		}
		configs = append(configs, &PrefixConfig{Prefix: bytes.TrimPrefix(kv.Key, keyPrefix), Config: config})
		sha.Write(kv.Value.Bytes)
	}
	m, err := NewPrefixConfigMap(configs)
	return m, sha.Sum(nil), err
}

// maybeAddToSplitQueue checks whether the current size of the range
// exceeds the max size specified in the zone config. If yes, the
// range is added to the split queue.
func (r *Range) maybeAddToSplitQueue() {
	maxBytes := r.GetMaxBytes()
	if maxBytes > 0 && r.stats.KeyBytes+r.stats.ValBytes > maxBytes {
		r.rm.splitQueue().MaybeAdd(r, r.rm.Clock().Now())
	}
}

redpajama_set_name: RedPajamaGithub


text:
Nicholas Pisanelli Barberton
BARBERTON/WADSWORTH---Nick Pisanelli, 94, loving husband, father, grandpa and friend, passed away peacefully surrounded by his adoring family on July 13. Born on Dec. 31, 1924 in Barberton with his twin Julius, he lived most of his life in Barberton where he met his wife of 69 yrs., Tommie. He served in WWII as a Tank Gunner with his brother Julius. He went to Kent State on the GI bill and received a degree in Business Administration. He was an Award-Winning Car Salesman, most notably at...
BARBERTON/WADSWORTH---Nick Pisanelli, 94, loving husband, father, grandpa and friend, passed away peacefully surrounded by his adoring family on July 13. Born on Dec. 31, 1924 in Barberton with...
Andrea Lloyd Barberton
BARBERTON---Andrea L. Lloyd, 54, passed away unexpectedly on July 13, 2019. Andrea was born in Barberton where she was a life resident and graduate of Barberton High School Class of 1983. She previously worked at Sterling Jewelers. Andrea loved baking and was well known for her Baklava, Apple Crisp and Popcorn she sold at the Barberton Farmer's Market. She also loved her beach trips. Most of all Andrea fought hard through numerous health complications over the past 15 years. She will...
BARBERTON---Andrea L. Lloyd, 54, passed away unexpectedly on July 13, 2019. Andrea was born in Barberton where she was a life resident and graduate of Barberton High School Class of 1983. She...
Thelma Miner Canton
Thelma Miner, age 81 passed away on July 10, 2019, surrounded by her family. She was born on July 20, 1937 in Canton, Ohio to the late Dorothy and Melvin Hayes. Thelma was the beloved wife of the late C. Eugene Miner for 43 years. She was also preceded in death by her two brothers, Bobby and Lyle Hayes. Thelma was a loving mother to Gene (Cathy) Miner, Scott (Carol) Miner, Renee (Denny) Pershin and Kim (Larry) Okolish. She was a dear Grandmother and Great Grandmother to her many grand and...
Thelma Miner, age 81 passed away on July 10, 2019, surrounded by her family. She was born on July 20, 1937 in Canton, Ohio to the late Dorothy and Melvin Hayes. Thelma was the beloved wife of the...
Allen Anderson Barberton
BARBERTON---Allen S. Anderson, 81 passed away peacefully at home on Friday, July 5th 2019. Allen graduated from Texas A&M with Bachelor degrees in Civil Engineering and Business Administration. He also earned a Masters degree in Business Administration. He later graduated from the University of Arkansas with a PhD in Finance. Allen was a proud Army veteran having served in the Korean War and retiring as a Lieutenant Colonel. During his service he graduated...
BARBERTON---Allen S. Anderson, 81 passed away peacefully at home on Friday, July 5th 2019. Allen graduated from Texas A&M with Bachelor degrees in Civil Engineering and Business...
Jeffrey Keefer Barberton
BARBERTON---Jeffrey L. Keefer, 54, went home to be with his Lord and Savior on July 4, 2019. Jeffrey was born in Barberton where he was a graduate of the Barberton High School Class of 1983 and a graduate of The University of Akron with an Associate's Degree in Commercial Art. He is survived by parents Okey and Marjorie; sisters Cynthia (Richard) Hayworth and Cathy (Perry) Brescilli; and four nephews, two nieces and two great nephews. . Jeffrey's Funeral Service will be held...
BARBERTON---Jeffrey L. Keefer, 54, went home to be with his Lord and Savior on July 4, 2019. Jeffrey was born in Barberton where he was a graduate of the Barberton High School Class of 1983 and a...
Christine Weigand Wadsworth
WADSWORTH---Christine Elaine Weigand, 54 passed away into the loving arms of our Lord on June 29, 2019. Born December 25, 1964 in Barberton, OH, she lived most of her life in Norton and Wadsworth. She was a 1983 graduate of Norton High School. She graduated from The University of Akron with a degree in Nursing, never letting anything stand in the way of accomplishing that dream. She recently retired from Cleveland Clinic Akron General after 30 years of service. She worked on the...
WADSWORTH---Christine Elaine Weigand, 54 passed away into the loving arms of our Lord on June 29, 2019. Born December 25, 1964 in Barberton, OH, she lived most of her life in Norton and...
John Bentfeld Barberton
BARBERTON---John K. Bentfeld, 78, passed away June 24, 2019. John was born in North Beaver Twp., PA and retired from Bliss Engineering and was the owner of Bentfeld Sharpening. He served in the US Army for 6-1/2 years as a combat engineer stationed at Kaiserslautern, Germany and also Ft. Dix, NJ. John coached football at United Local for many years and loved the Pittsburgh Steelers. Preceded in death by his parents Charles and Ethel; brother Gary; and granddaughter Amanda Elise Fortune;...
BARBERTON---John K. Bentfeld, 78, passed away June 24, 2019. John was born in North Beaver Twp., PA and retired from Bliss Engineering and was the owner of Bentfeld Sharpening. He served in the US...
Patricia Jursik Barberton
BARBERTON---Patricia A. Jursik (nee Kotnik), 90, passed away June 19, 2019 surrounded by her family. Pat was born in Cleveland and had been a Barberton resident all her life. She retired from the Babcock and Wilcox Co. after 22 years of service. She also worked at Yoder Bros., Seiberling Latex, and Sparkle Market. Pat was a member of Prince of Peace Catholic Church, the Mother of Seven Sorrows Altar Society, KSKJ Lodge 111, the Slovene Pensioners and Domovina Lodge. She was a wonderful cook...
BARBERTON---Patricia A. Jursik (nee Kotnik), 90, passed away June 19, 2019 surrounded by her family. Pat was born in Cleveland and had been a Barberton resident all her life. She retired from the...
Gladys Matuch Barberton
BARBERTON---Gladys M. Matuch, 76, passed away Thursday, June 13, 2019 at Summa Barberton Hospital. Born on May 5, 1943 in Prattsville, OH to the late Elmer and Lucille (Peters) Allman, she had been a Barberton area resident most of her life and was a member of the Barberton Kingdom Hall of Jehovah's Witness. Gladys was also a member of the OSTPA and enjoyed tractor pulls, camping, crafting and quilting. In addition to her parents, she was preceded in death by her husband, Bruce...
BARBERTON---Gladys M. Matuch, 76, passed away Thursday, June 13, 2019 at Summa Barberton Hospital. Born on May 5, 1943 in Prattsville, OH to the late Elmer and Lucille (Peters) Allman, she had...
George Strauch Barberton
BARBERTON---George W. Strauch, 101, was called to his eternal rest on June 13, 2019, surrounded by his loving daughters. He was born March 28, 1918 in Helen, PA and grew up in nearby Keisterville. He graduated from Uniontown High School in 1937. George joined the Army Air Corps in 1942 and served as a B-24 bomber mechanic/ technical inspector. He received an Honorable Discharge in Feb 1946, having attained the rank of Staff Sergeant. He returned to Keisterville and married his longtime...
BARBERTON---George W. Strauch, 101, was called to his eternal rest on June 13, 2019, surrounded by his loving daughters. He was born March 28, 1918 in Helen, PA and grew up in nearby Keisterville....

redpajama_set_name: RedPajamaCommonCrawl


text:
Not-so-similar fate of identical twins infected with HIV-1
For extra credit in my recently concluded virology course, I asked students to summarize a virology finding in the style of this blog. I received many excellent submissions which I plan to post here in the coming months.
by Amanda Carpenter
In 1983, identical twin boys simultaneously received a contaminated blood transfusion immediately after birth, and were subsequently diagnosed with HIV-1. Years later, one of the twins is faring very well and has a near normal immune system, while the other is in poor health and has experienced many complications. How could the same virus, infecting two individuals at the same time, with the same genetic background, yield such different clinical courses? This unfortunate natural experiment has allowed researchers to study viral evolution while holding host genetic make-up constant. Brigham Young University Chairman of Biology Keith Crandall has studied the virus in this interesting case and recently published his findings in BMC Evolutionary Biology.
Crandall's team examined blood samples obtained from the twins when they were 15 years old. They collected nucleotide sequence data from several genes essential to the success of HIV infection, which allowed them to extrapolate rates of viral growth, recombination, and genetic diversity. They reported that the virus of the healthier twin exhibited generally higher growth rates, higher genetic diversity, and higher recombination rates than the virus of the sicker twin (2).
How is this possible? Infected individuals produce an estimated 1010 new HIV virions every day, with errors occurring at a rate of about 1 per 104 nucleotides incorporated (1). These frequent point mutations are a simple starting point to explain the divergence of a once identical virus. In addition, HIV virions are capable of exchanging their genetic material with a different strain of virus via a process called recombination. Recombination is likely a random event, but has important implications for the host immune system.
Part of the immune system's response to HIV is the utilization of cytotoxic T lymphocytes (CD8+ cells), which target and kill virus-infected cells. These cells are very specific, and if a recombination event occurs, these cytotoxic cells may not be able to recognize the new viral strain as readily as the original. The immune system may adapt to the new strain, but the virus may recombine again and again, and the immune system will not be able to keep up. These recombinant strains are likely to become more prevalent through natural selection. If recombined strains are better at evading the immune system, and are therefore more detrimental to the host, does this mean they are more successful? Why would the virus that has higher genetic diversity, a growth rate, and a higher recombination rate cause less disease? Perhaps the answer lies in the immune system.
Once out of the womb, these twins no longer exist in identical environments. They are exposed to different pathogens, bacteria, and microbes, all of which affect the make-up of the immune system. The healthier twin's immune system may be better able to fight the virus, and so the virus must grow, diversify, and recombine in order to propagate the infection. In other words, because the sicker twin has a more depressed immune system, the virus is replicating with less resistance, and there is less incentive for the virus to evolve. Divergent viral evolution in the case of these monozygotic twins is likely due to random mutation and recombination events, combined with antiviral pressure from the hosts, whose immune systems are not identical at all.
(1)	Yang, O., Church, J., Kitchen, C., Kilpatrick, R., Ali, A., Geng, Y., Killian, M., Sabado, R., Ng, H., Suen, J., Bryson, Y., Jamieson, B., & Krogstad, P. (2005). Genetic and Stochastic Influences on the Interaction of Human Immunodeficiency Virus Type 1 and Cytotoxic T Lymphocytes in Identical Twins Journal of Virology, 79 (24), 15368-15375 DOI: 10.1128/JVI.79.24.15368-15375.2005
(2)	Tazi L, Imamichi H, Hirschfeld S, Metcalf JA, Orsega S, Pérez-Losada M, Posada D, Lane HC, & Crandall KA (2011). HIV-1 infected monozygotic twins: a tale of two outcomes. BMC evolutionary biology, 11 PMID: 21385447
Hanna says
Off topic but, do you have permission to use the Arbus pic.? The very least you should do is credit the artist.thanks
profvrr says
The photo is linked to a credit.
RRM says
Enlightening. Thank you for that. PS: It seems that Stanley Kubrick liked that Arbus pic too.
Maria Bogdanovskaya says
Dear Dr Racanielo,
I was wondering whether these differences between
monozygotic twins (MZ) could result from other causes as well.
In the first place, it has recently been proposed
that there are epigenetic differences between MZ twins (Fraga et al., 2005);
the effect of these epigenetic differences seems to increase during
development. Do you think that could have affected the differences between the
HIV-1 response in these MZ twins?
Also, I was wondering if the effects of immune
system activation on the HIV-1 recombination and consequences for one's health may be the
other way round. I used to think that at least some of the damage produced by HIV infection is due to the prolonged activation of the immune system that is not capable of eliminating the pathogen. This may have produced worse complications in a twin with stronger immune response. In addition, as HIV can only replicate in activated CD4+ T cells, greater activation of the immune system produces greater viral titre and, consequently, more complications. Do you think these factors could affect the differences between the HIV-1 response in these MZ twins?
Thanks a lot in advance!
Also, thank you very much for your blog, I greatly enjoy reading it.
Maria (a Physiology undergraduate somewhere in the UK)
William Khoury-Hanold says
A very thoughtful commentary, however, I don't think that this scenario is " holding host genetic make-up constant." Besides the epigenetic differences between monozygotic twins –a point previously raised by another commenter and in ref. 1– twins also differ in their T and B cell repertoires. During T and B cell development, recombination events at the TCR and BCR loci give raise to an incredibly diverse set of antigen specific cells; many of these specificities are unique to each twin and are the only genetic differences between monozygotic twins. Therefore, it is conceivable that the differences in the twins' ability to control viral load is not only rooted in their epigenetic differences but also in their ability to produce HIV-specific T and B cell responses.
Lane Yarbrough says
I started working in one of the countries first AIDS hospices. I too contracted HIV in 1990. I have never had an HIV/AIDS defining illness. It has been 20 years and I have been amazed how this virus ravishes some and never seems to take hold in people such as myself. I have attended support groups, mainly due to the fear of dieing'; dieing like the residents at the hospice, horrible and terrible to witness. But then I was told that some people died from the medications, we had 10 residents die in a few years from pancreatic disorders caused from some of the pharmaceutical therapies. The reason I started working at the hospice, I was called into the office by my nursing agency, they wanted me to work a "special" case. It was the first AIDS patient any agency in Seattle attempted to staff, most of the patients were confined to hospitals then. I will never forget how they responded when I said yes, sick is "sick" isn't it" I can't pick and choose. Today I still have nightmares about what the medical community did to this guy, he didn't end up dieing from AIDS, it was radiation poisoning from all the "we'll try this" treatment.
How do you suggest I stop my doctors from blaming age/environment related health issues on my HIV? I have received WORSE health care because most of them just say, "Oh, that's typical of HIV infection". I have had carpal tunnel syndrome since I was 13, but the doctor diagnosed me a few weeks ago with HIV neuropathy. AAAHHH!
Airramone says
I wonder if anyone has considered the sexual role of the twins- perhaps the sicker twin is more passive, and has been receiving sexual activity from his more dominant twin brother? It seems the dominant ( top) position gay men suffer fewer HIV contractions than the passive (bottom) men; attributed to the tearing of the anal tissue and exposing openings for the virus to enter the blood stream
Amy Payne says
A third interpretation of this story is that mutant HIV is less robust than non-resistant "wild-type" HIV. Therefore the less-mutated HIV reproduces with greater efficiency and thus greater numbers than a more mutated HIV strain. This has been hypothesized to explain the effect that "drug vacations" have on HIV drug resistance. HIV that is resistant to protease inhibitors has been shown to be less efficient than HIV that is not resistant to protease inhibitors. There is a series of articles from 1998-200x on using evolutionary models to predict the presence of antiretroviral resistance in HIV populations within an individual. Unfortunately I don't have the wherewithal to look it back up right now. Anybody else know the status of this model?
Steven Keirstead says
You should credit Diane Arbus for the photo of the twins on this post.
Dtomlin1 says
This is hard to believe that identical twins would have such different immune systems. Maybe one had more nutrition in the womb than the other.
Not that it matters to me, but giving attribution on a copyright infringement is not a legal defense – though it might mollify the rights holder, only if they so choose.
The DMCA provides for statutory damages, so the owner doesn't have to prove actual damages. Also, since there is a link to a book for sale, this would qualify as commercial infringement on the part of the website owner – with larger damages.
That's just a friendly head's up, I don't personally care either way.
Ergonomic Chair says
9 June 2011 at 2:56 am
This is a very interesting post and it just goes to show the chance for distinct differences to take place out of a supposedly identical subject. Good health is a blessing that people should never disregard because it will be the best way for you to experience the best of life.
Christopher Pinney says
aids and radiation poisoning are one and the same thing. i have come to that conclusion after five years of study. A.I.D.S = ATOMIC INDUCED DISEASE SYNDROME.
chris pinney.
FreeTetris says
With websites that allow you to download Pacman, now you can experience it for yourself.
Have you created a situation where you have one
foot out the door, just in case things don't work out. Companies are being set up to come up with ideas for apps and produce them for the growing market that the i – Phone has spawned. Meanwhile, Goofy wants the stone as a hood for his tractor, and Minnie wishes to have it made into a necklace. While it is certainly true that you can have a lot of fun playing Tetris, very few people realize that you can actually enhance the functionality of your mind by playing this particular game.


The independent Local Government Boundary Commission for England has opened a new phase of public consultation in its review of Isle of Wight Council's division boundaries.
The consultation focuses on new proposals for division boundaries in three parts of the island: Freshwater and Totland, Ryde and Ventnor and Wroxall.
Local people have until1 April 2019 to have their say on the proposals before the Commission finalises its recommendations for new divisions across the whole island in June.
In September 2018, the Commission opened a public consultation on proposals for new division boundaries across Isle of Wight. In response to local feedback on the plans, the Commission has decided to make significant changes to their boundary proposals in three parts of the island. Due to the extent of the proposed changes, the Commission is holding an extra round of consultation before it finalises the recommendations.
Professor Colin Mellors, Chair of the Commission, said: "We listened carefully to all the views put to us in the previous consultation and have made significant changes to the original recommendations in some parts of the island.
In the west of the island, the Commission has decided to change its original recommendations so that the shopping area around Avenue Road will be part of a Freshwater division rather than Totland as previously proposed. Local people and groups argued that the area is a fundamental part of Freshwater and not Totland.
The Commission has also changed their proposals so that the area of Colwell would be part of the Totland division rather than Freshwater as previously proposed. The Commission received persuasive evidence during the public consultation that this amended proposal would be a better reflection of local community ties.
In Ryde, the Commission has clarified its proposal for the boundary between Ryde North East and Ryde South East divisions so that it would run along West Hill Road and Park Road. Mapping published by the Commission on its website during the earlier consultation had incorrectly marked St Johns Hill as the proposed boundary. To avoid confusion, the Commission is giving local people another opportunity to comment on the boundary proposals in Ryde.
In the south of island, the Commission originally proposed a Ventnor & Wroxall division to cover both communities in an area that would be represented by two councillors. The Commission listened to local objections regarding its draft recommendations and has decided to put forward a new plan for two divisions, each to be represented by one councillor. The Commission believes its proposed Ventnor East & Wroxall and Ventnor West divisions are a better reflection of community ties in this area.
The consultation is limited to the Commission's new proposals in the three areas of the Isle of Wight. Details of the recommendations, including maps of the proposals, are available on the Commission's website at www.lgbce.org.uk and at https://consultation.lgbce.org.uk/node/12655.
Residents have from 5 March until 1 April 2019 to have their say about where division boundaries in Isle of Wight should be drawn. The Commission will consider all submissions and aims to publish its final recommendations in June 2019. Once the Commission agrees its final recommendations it will lay a draft order in both Houses of Parliament. Parliament will then have 40 days in which to consider the recommendations. If both Houses are satisfied with the recommendations, the draft order will be 'made' and the new divisions will come into effect at the council elections in 2021.
The Commission is satisfied that it has received sufficient evidence to finalise new division boundaries for the rest of Isle of Wight and aims to publish a full set of final recommendations for the council in June.