<commit_before>use hash::HASH_SIZE;
use hash::Hash;
use std::net;
use std::collections::VecDeque;
use std::mem;
use std::sync::Mutex;

#[cfg(test)]
mod tests;

pub const ALPHA    : usize = 3;
pub const K        : usize = 20;
const BUCKET_DEPTH : usize = K;

/// Kademlia routing table, with 160 buckets of `BUCKET_DEPTH` (k) node
/// identifiers each, constructed around a parent node ID.
///
/// The structure employs least-recently seen eviction. Conflicts generated
/// by evicting a node by inserting a newer one remain tracked, so they can
/// be resolved later.
pub struct Table {
   buckets        : Vec<Bucket>,
   conflicts      : Mutex<Vec<EvictionConflict>>,
   parent_node_id : Hash,
}

#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct NodeInfo {
   pub node_id : Hash,
   pub address : net::SocketAddr,
}

#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub enum LookupResult {
   Myself,
   Found(NodeInfo),
   ClosestNodes(Vec<NodeInfo>),
}

impl Table {
   /// Constructs a routing table based on a parent node id. Other nodes
   /// will be stored in this table based on their distance to the node id provided.
   pub fn new(parent_node_id: Hash) -> Table {
      let mut buckets = Vec::<Bucket>::with_capacity(HASH_SIZE);
      for _ in 0..HASH_SIZE {
         buckets.push(Bucket::new());
      }

      Table {
         buckets        : buckets,
         conflicts      : Mutex::new(Vec::new()),
         parent_node_id : parent_node_id,
      }
   }

   /// Inserts a node in the routing table. Employs least-recently-seen eviction
   /// by kicking out the oldest node in case the bucket is full, and registering
   /// an eviction conflict that can be revised later.
   pub fn insert_node(&self, info: NodeInfo) {
      if let Some(index) = self.bucket_for_node(&info.node_id) {
         let bucket = &self.buckets[index];
         let mut entries = bucket.entries.lock().unwrap();

         entries.retain(|ref stored_info| info.node_id != stored_info.node_id);
         if entries.len() == BUCKET_DEPTH {
            let conflict = EvictionConflict {
               evicted  : entries.pop_front().unwrap(),
               inserted : info.clone()
            };
            let mut conflicts = self.conflicts.lock().unwrap();
            conflicts.push(conflict);
         }
         entries.push_back(info);
      }
   }

   /// Performs a node lookup on the routing table. The lookup result may
   /// contain the specific node, a list of up to the N closest nodes, or
   /// report that the parent node itself was requested.
   ///
   /// This employs an algorithm I have named "bounce lookup", which obtains
   /// the closest nodes to a given origin walking through the minimum
   /// amount of buckets. It may exist already, but I haven't
   /// found it any other implementation. It consists of:
   ///
   /// * Calculating the XOR distance between the parent node ID and the
   ///   lookup node ID.
   ///
   /// * Checking the buckets indexed by the position of every "1" in said
   ///   distance hash, in descending order.
   ///
   /// * "Bounce" back up, checking the buckets indexed by the position of
   ///   every "0" in that distance hash, in ascending order.
   pub fn lookup(&self, node_id: &Hash, n: usize, blacklist: Option<&Vec<Hash>>) -> LookupResult {
      if node_id == &self.parent_node_id {
         return LookupResult::Myself;
      }

      match self.specific_node(node_id) {
         Some(info) => LookupResult::Found(info),
         None => LookupResult::ClosestNodes(self.closest_n_nodes_to(node_id, n, blacklist)),
      }
   }

   /// Returns an iterator over all stored nodes, ordered by ascending
   /// distance to the parent node. This iterator is designed for concurrent
   /// access to the data structure, and as such it isn't guaranteed that it
   /// will return a "snapshot" of all nodes for a specific moment in time.
   /// Buckets already visited may be modified elsewhere through iteraton,
   /// and unvisited buckets may accrue new nodes.
   pub fn all_nodes(&self) -> AllNodes {
      AllNodes {
         table          : self,
         current_bucket : Vec::with_capacity(BUCKET_DEPTH),
         bucket_index   : 0,
      }
   }

   /// Returns a table entry for the specific node with a given hash.
   pub fn specific_node(&self, node_id: &Hash) -> Option<NodeInfo> {
      if let Some(index) = self.bucket_for_node(node_id) {
         let entries = &self.buckets[index].entries.lock().unwrap();
         return entries.iter().find(|ref info| *node_id == info.node_id).cloned();
      }
      None
   }

   /// Bounce lookup algorithm.
   fn closest_n_nodes_to(&self, node_id: &Hash, n: usize, blacklist: Option<&Vec<Hash>>) -> Vec<NodeInfo> {
      let mut closest = Vec::with_capacity(n);
      let distance = &self.parent_node_id ^ node_id;
      let descent  = distance.ones().rev();
      let ascent   = distance.zeroes();
      let lookup_order = descent.chain(ascent);

      for bucket_index in lookup_order {
         let entries = self.buckets[bucket_index].entries.lock().unwrap();
         if entries.is_empty() {
            continue;
         }

         let mut nodes_from_bucket = entries.clone().into_iter().collect::<Vec<NodeInfo>>();
         if let Some(blacklist) = blacklist {
            nodes_from_bucket.retain(|node: &NodeInfo| !blacklist.contains(&node.node_id));
         }

         nodes_from_bucket.sort_by_key(|ref info| &info.node_id ^ node_id);
         let space_left = closest.capacity() - closest.len();
         nodes_from_bucket.truncate(space_left);
         closest.append(&mut nodes_from_bucket);

         if closest.len() == closest.capacity() {
            break;
         }
      }
      closest
   }

   /// Returns the appropriate position for a node, by computing
   /// the index where their prefix starts differing. If we are requesting
   /// the bucket for this table's own parent node, it can't be stored.
   fn bucket_for_node(&self, node_id: &Hash) -> Option<usize> {
       (&self.parent_node_id ^ node_id).height()
   }

   fn revert_conflict(&self, conflict: EvictionConflict) {
      if let Some(index) = self.bucket_for_node(&conflict.inserted.node_id) {
         let mut entries = self.buckets[index].entries.lock().unwrap();
         let evictor = &mut entries.iter_mut().find(|ref info| conflict.inserted.node_id == info.node_id).unwrap();
         mem::replace::<NodeInfo>(evictor, conflict.evicted);
      }
   }
}

/// Produces copies of all known nodes, ordered in ascending
/// distance from self. It's a weak invariant, i.e. the table
/// may be modified through iteration.
pub struct AllNodes<'a> {
   table          : &'a Table,
   current_bucket : Vec<NodeInfo>,
   bucket_index   : usize,
}

/// Represents a conflict derived from attempting to insert a node in a full
/// bucket.
#[derive(Debug,Clone)]
struct EvictionConflict {
   evicted  : NodeInfo,
   inserted : NodeInfo
}

/// Bucket size is estimated to be small enough not to warrant
/// the downsides of using a linked list.
///
/// Each vector of bucket entries is protected under its own mutex, to guarantee
/// concurrent access to the table.
#[derive(Debug)]
struct Bucket {
   entries: Mutex<VecDeque<NodeInfo>>,
}

impl<'a> Iterator for AllNodes<'a> {
   type Item = NodeInfo;

   fn next(&mut self) -> Option<NodeInfo> {
      while self.bucket_index < HASH_SIZE && self.current_bucket.is_empty() {
         let mut new_bucket = { // Lock scope
            self.table.buckets[self.bucket_index].entries.lock().unwrap().clone()
         }.into_iter().collect::<Vec<NodeInfo>>();

         new_bucket.sort_by_key(|ref info| &info.node_id ^ &self.table.parent_node_id);
         self.current_bucket.append(&mut new_bucket);
         self.bucket_index += 1;
      }
      self.current_bucket.pop()
   }
}

impl Bucket {
   fn new() -> Bucket {
      Bucket{
         entries: Mutex::new(VecDeque::with_capacity(BUCKET_DEPTH))
      }
   }
}
<commit_msg>RwLock for buckets<commit_after>use hash::HASH_SIZE;
use hash::Hash;
use std::net;
use std::collections::VecDeque;
use std::mem;
use std::sync::{Mutex, RwLock};

#[cfg(test)]
mod tests;

pub const ALPHA    : usize = 3;
pub const K        : usize = 20;
const BUCKET_DEPTH : usize = K;

/// Kademlia routing table, with 160 buckets of `BUCKET_DEPTH` (k) node
/// identifiers each, constructed around a parent node ID.
///
/// The structure employs least-recently seen eviction. Conflicts generated
/// by evicting a node by inserting a newer one remain tracked, so they can
/// be resolved later.
pub struct Table {
   buckets        : Vec<Bucket>,
   conflicts      : Mutex<Vec<EvictionConflict>>,
   parent_node_id : Hash,
}

#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct NodeInfo {
   pub node_id : Hash,
   pub address : net::SocketAddr,
}

#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub enum LookupResult {
   Myself,
   Found(NodeInfo),
   ClosestNodes(Vec<NodeInfo>),
}

impl Table {
   /// Constructs a routing table based on a parent node id. Other nodes
   /// will be stored in this table based on their distance to the node id provided.
   pub fn new(parent_node_id: Hash) -> Table {
      let mut buckets = Vec::<Bucket>::with_capacity(HASH_SIZE);
      for _ in 0..HASH_SIZE {
         buckets.push(Bucket::new());
      }

      Table {
         buckets        : buckets,
         conflicts      : Mutex::new(Vec::new()),
         parent_node_id : parent_node_id,
      }
   }

   /// Inserts a node in the routing table. Employs least-recently-seen eviction
   /// by kicking out the oldest node in case the bucket is full, and registering
   /// an eviction conflict that can be revised later.
   pub fn insert_node(&self, info: NodeInfo) {
      if let Some(index) = self.bucket_for_node(&info.node_id) {
         let bucket = &self.buckets[index];
         let mut entries = bucket.entries.write().unwrap();

         entries.retain(|ref stored_info| info.node_id != stored_info.node_id);
         if entries.len() == BUCKET_DEPTH {
            let conflict = EvictionConflict {
               evicted  : entries.pop_front().unwrap(),
               inserted : info.clone()
            };
            let mut conflicts = self.conflicts.lock().unwrap();
            conflicts.push(conflict);
         }
         entries.push_back(info);
      }
   }

   /// Performs a node lookup on the routing table. The lookup result may
   /// contain the specific node, a list of up to the N closest nodes, or
   /// report that the parent node itself was requested.
   ///
   /// This employs an algorithm I have named "bounce lookup", which obtains
   /// the closest nodes to a given origin walking through the minimum
   /// amount of buckets. It may exist already, but I haven't
   /// found it any other implementation. It consists of:
   ///
   /// * Calculating the XOR distance between the parent node ID and the
   ///   lookup node ID.
   ///
   /// * Checking the buckets indexed by the position of every "1" in said
   ///   distance hash, in descending order.
   ///
   /// * "Bounce" back up, checking the buckets indexed by the position of
   ///   every "0" in that distance hash, in ascending order.
   pub fn lookup(&self, node_id: &Hash, n: usize, blacklist: Option<&Vec<Hash>>) -> LookupResult {
      if node_id == &self.parent_node_id {
         return LookupResult::Myself;
      }

      match self.specific_node(node_id) {
         Some(info) => LookupResult::Found(info),
         None => LookupResult::ClosestNodes(self.closest_n_nodes_to(node_id, n, blacklist)),
      }
   }

   /// Returns an iterator over all stored nodes, ordered by ascending
   /// distance to the parent node. This iterator is designed for concurrent
   /// access to the data structure, and as such it isn't guaranteed that it
   /// will return a "snapshot" of all nodes for a specific moment in time.
   /// Buckets already visited may be modified elsewhere through iteraton,
   /// and unvisited buckets may accrue new nodes.
   pub fn all_nodes(&self) -> AllNodes {
      AllNodes {
         table          : self,
         current_bucket : Vec::with_capacity(BUCKET_DEPTH),
         bucket_index   : 0,
      }
   }

   /// Returns a table entry for the specific node with a given hash.
   pub fn specific_node(&self, node_id: &Hash) -> Option<NodeInfo> {
      if let Some(index) = self.bucket_for_node(node_id) {
         let entries = &self.buckets[index].entries.read().unwrap();
         return entries.iter().find(|ref info| *node_id == info.node_id).cloned();
      }
      None
   }

   /// Bounce lookup algorithm.
   fn closest_n_nodes_to(&self, node_id: &Hash, n: usize, blacklist: Option<&Vec<Hash>>) -> Vec<NodeInfo> {
      let mut closest = Vec::with_capacity(n);
      let distance = &self.parent_node_id ^ node_id;
      let descent  = distance.ones().rev();
      let ascent   = distance.zeroes();
      let lookup_order = descent.chain(ascent);

      for bucket_index in lookup_order {
         let entries = self.buckets[bucket_index].entries.read().unwrap();
         if entries.is_empty() {
            continue;
         }

         let mut nodes_from_bucket = entries.clone().into_iter().collect::<Vec<NodeInfo>>();
         if let Some(blacklist) = blacklist {
            nodes_from_bucket.retain(|node: &NodeInfo| !blacklist.contains(&node.node_id));
         }

         nodes_from_bucket.sort_by_key(|ref info| &info.node_id ^ node_id);
         let space_left = closest.capacity() - closest.len();
         nodes_from_bucket.truncate(space_left);
         closest.append(&mut nodes_from_bucket);

         if closest.len() == closest.capacity() {
            break;
         }
      }
      closest
   }

   /// Returns the appropriate position for a node, by computing
   /// the index where their prefix starts differing. If we are requesting
   /// the bucket for this table's own parent node, it can't be stored.
   fn bucket_for_node(&self, node_id: &Hash) -> Option<usize> {
       (&self.parent_node_id ^ node_id).height()
   }

   fn revert_conflict(&self, conflict: EvictionConflict) {
      if let Some(index) = self.bucket_for_node(&conflict.inserted.node_id) {
         let mut entries = self.buckets[index].entries.write().unwrap();
         let evictor = &mut entries.iter_mut().find(|ref info| conflict.inserted.node_id == info.node_id).unwrap();
         mem::replace::<NodeInfo>(evictor, conflict.evicted);
      }
   }
}

/// Produces copies of all known nodes, ordered in ascending
/// distance from self. It's a weak invariant, i.e. the table
/// may be modified through iteration.
pub struct AllNodes<'a> {
   table          : &'a Table,
   current_bucket : Vec<NodeInfo>,
   bucket_index   : usize,
}

/// Represents a conflict derived from attempting to insert a node in a full
/// bucket.
#[derive(Debug,Clone)]
struct EvictionConflict {
   evicted  : NodeInfo,
   inserted : NodeInfo
}

/// Bucket size is estimated to be small enough not to warrant
/// the downsides of using a linked list.
///
/// Each vector of bucket entries is protected under its own mutex, to guarantee
/// concurrent access to the table.
#[derive(Debug)]
struct Bucket {
   entries: RwLock<VecDeque<NodeInfo>>,
}

impl<'a> Iterator for AllNodes<'a> {
   type Item = NodeInfo;

   fn next(&mut self) -> Option<NodeInfo> {
      while self.bucket_index < HASH_SIZE && self.current_bucket.is_empty() {
         let mut new_bucket = { // Lock scope
            self.table.buckets[self.bucket_index].entries.read().unwrap().clone()
         }.into_iter().collect::<Vec<NodeInfo>>();

         new_bucket.sort_by_key(|ref info| &info.node_id ^ &self.table.parent_node_id);
         self.current_bucket.append(&mut new_bucket);
         self.bucket_index += 1;
      }
      self.current_bucket.pop()
   }
}

impl Bucket {
   fn new() -> Bucket {
      Bucket{
         entries: RwLock::new(VecDeque::with_capacity(BUCKET_DEPTH))
      }
   }
}
<|endoftext|>


<commit_before>/// Data used for a TimeSteward simulation, such as times, entities, and events.
///
/// TimeSteward has strong requirements for serializability. In addition to implementing these traits, a StewardData must have Eq be equivalent to equality of its serialization, and all its behavior must be invariant under cloning and serialize-deserialize cycles.
pub trait StewardData: Any + Send + Sync + Clone + Eq + Serialize + Deserialize + Debug {}

trait TimeStewardModificationReverter {
  fn revert (event: ?????)->invalidated stuff etc., like the return value of the original modify functions;
}

/**

Loosely speaking, these must be retroactive data structures.

Specifically, I'll call them **stack-retroactive data structures**. They are like fully retroactive data structures, except that operations in the past are also permitted to delete arbitrary subsets of the existing operations that are later in time. This leniency is because:
* Data structures can be more efficient if they don't have to support insertion or deletion in the middle, and
* In many cases, the later operations would almost certainly be invalidated anyway if the earlier one was invalidated.

They must obey these conditions:
* The result of a query from a non-snapshot accessor must depend only on the initial snapshot and currently existing operations, and not, for instance, on the order the operations were added. It MAY depend on the order of operations among operations at the exact same ExtendedTime. Query results must also be invariant under taking snapshots at earlier historical times and restoring from them.
* Also, the existing predictors are implicit in the current state. They may not change over serializing and deserializing through a snapshot.
* The results of a query/snapshot from a *snapshot accessor* must depend only on the initial snapshot and operations that existed *at the time the snapshot accessor was created*. (In order to maintain this condition, the structure may have to examine the supplied snapshots structure during insert_operation().) This condition may be violated if forget_snapshot() has been called for that snapshot.
* If a change to the operations would change the result of an earlier query (earlier in program time, >= in historical time), and that earlier query submitted a InvalidationHandle, that update operation must invalidate it by including an equal InvalidationHandle in its return value. (False-positives are permitted, though undesirable). It need only return each InvalidationHandle once. Note that it does NOT have to retain copies of every handle submitted, if it has some way of looking them up, for example by querying other DataTimelines.
* Any method called at a historical time > self.valid_since() must return Ok. self.valid_since() must be TheBeginning when a with_steward() is created, and After (time) when a from_snapshot() is created. It must not increase except from calls to discard_before or insert_operation, and if it implements FullDataTimeline, it must not increase from calls to insert_operation either.

They also *should* obey these conditions:
* whenever the structure stores obsolete information to maintain a snapshot, it should notify the snapshot using ????? so that the snapshot may free up the memory using forget_snapshot() when it is dropped.

*/
struct QueryResult <Timeline: DataTimeline> {
  data: Timeline::QueryResultData;
  valid_until: something < ExtendedTime <Whatever::Steward::Basics>>;
}
struct OperationResult <Timeline: DataTimeline> {
  invalidated_queries: Vec<InvalidationHandle>;
  deleted_future_operations: Vec<(EventHandle, Operation)>; ?????
  created_predictors: Vec<PredictorHandle>;
  deleted_predictors: Vec<PredictorHandle>;
}
struct FromSnapshotResult <Timeline: DataTimeline> {
  created_predictors: Vec<PredictorHandle>;
}
// DataTimeline handles serialize to DataTimelineId
//but the id probably won't be stored in the trait implementor
 // fn id (&self)->DataTimelineId;
trait DataTimeline: Any + UniquelyIdentifiedType {

  type Steward: TimeSteward;
  type Constants: StewardData;

  // All inputs are required to have a standard format, so that the structure can be audited.
  type Query: StewardData;
  type QueryResultData: StewardData;
  type Operation: StewardData;
  type Snapshot: StewardData;

  fn from_constants (steward: StewardHandle <Self::Steward>, constants: Self::Constants)->Self;
  fn from_snapshot (steward: StewardHandle <Self::Steward>, snapshot: &Self::Snapshot)->Self;

  fn constants (&self)->Result <QueryResult<Self>,>;
  fn query <A: Accessor> (&self, query: Self::Query, accessor: &A)->Result <QueryResult<Self>,>;

  // note: I'm not sure this needs an error mode, because having a snapshot prior to the valid_since of a data timeline might be a caller error in a TimeSteward
  fn snapshot (snapshot: &Self::Steward::Snapshot)->Snapshot;

  /// requires a &Steward only so that you can't do it in a predictor or event function.
  //Maybe this should also return a range of times changed so you know what snapshots need to be taken?
  fn insert_operation <Snapshots: SnapshotTree> (&mut self, time: ExtendedTime <Self::Steward::Basics>, operation: Self::Operation, snapshots_to_maintain: & Snapshots, & Steward)->Result <,>;

  fn valid_since (&self, & Steward)->ValidSince <ExtendedTime <Self::Steward::Basics>>;

  fn forget_before (&mut self, time: ExtendedTime <Self::Steward::Basics>, & Steward);
  fn forget_snapshot (&mut self, StewardRc <Steward::Snapshot>);

  // query functions, which take an accessor and possibly a prediction handle, which may be stored in self for future invalidation
  // modify functions, which take a mutator and
  // - possibly return invalidated prediction handles
  // – possibly return spawned predictions, as from creating a new entity
  // - assuming this is for a full TimeSteward, return a StewardRc <TimeStewardModificationReverter> (which, for the simple case, may be a Self). This makes each potential reversion take at least a fat-pointer to store, unless we can make StewardRc be a thin pointer with the vtable at the destination.

  //An operation at time T may create new predictors from T to other times, destroy predictors from T to other times, or invalidate predictions that include After (T).
}

trait SnapshotTree {
  type Steward: TimeSteward;
  fn iterate_snapshots (&self, time_range, since_snapshot_number)->impl Iter<Item = (& Self::Steward::Basics::Time, &StewardRc <Self::Steward::Snapshot>)>;
}

// Model: events interact only through queries at their exact time (which are forbidden to query other timelines or have any side effects) and modifications at their exact time (which are forbidden to return any information). Those modifications, in practice, change the state *going forward from* that time, and may use query_range on other timelines to collect events/predictions that must be invalidated. (Although for instance, modifications made for dependency tracking purposes don't change any results of "real" queries (i.e. those by events and predictors), so they never need to invalidate anything themselves.)
// Predictors cannot modify and can only query??? (The data necessary to invalidate them has to be placed by the events that created them?)
//To audit, we record all of the queries, query results, and modifications. Then after each modification of a DataTimeline, we rerun all queries to that timeline made by still-valid predictions/events. If any query has a different result than before, it's an error. (I guess in order to rerun modifications, we have to feed them the old results of their queries instead of having them do real queries?)
// Also audit: a modification can never change results of queries in the past

// Given a query input, the function (time->query output) must be piecewise constant, changing only at times when modifications have been inserted.
// Event must implement undo. That must call the undo function matching all modifications it made. After an event is undone, there may not remain any modifications at the time of that event. It follows that after doing and then undoing an event, all queries IMMEDIATELY after the event time are restored to their former value. However, queries in the future might not be restored because modifications are permitted to mess up the future(?)

trait DataTimeline: Any {
  // audit: result NEVER changes unless forget_snapshot() is called
  // audit: restoring from version serialized using fresh snapshot doesn't change any query results afterwards
  fn serialize (&self, serializer: &mut something, snapshot: SnapshotHandle);
  fn deserialize (deserializer: something, time: ExtendedTime)->Self;

  // audit: forget functions don't change any query results except those forgotten
  fn forget_before (&mut self, time: ExtendedTime);
  fn forget_snapshot (&mut self, snapshot: SnapshotHandle);
}
trait DataTimelineQueriableWith<Query: StewardData>: DataTimeline {
  type QueryResult: StewardData;

  // audit all functions: must be consistent with each other
  // audit: queries must not have side effects (do a separate action for manual dependency tracking)
  fn query (&self, query: Query, time: ExtendedTime)->QueryResult;
  // permitted to record the dependency
  fn prediction_query (&mut self, query: Query, time: ExtendedTime, predictor: PredictorHandle)->(QueryResult, Option <ExtendedTime>);
  // TODO: is this necessary? Or is it only used in invalidation code, which can peek anyway?
  fn query_range (&self, query: Query, time_range: TimeRange)->impl Iter <Item = (TimeRange, QueryResult)>;

  // audit: NEVER changes unless forget_snapshot() is called
  fn snapshot_query (&self, query: Query, snapshot: SnapshotHandle)->QueryResult;
}
trait DataTimelineModifiableWith<Modification: StewardData>: DataTimeline {
  type DataToUndoModification: StewardData;

  // audit both functions: calls invalidate_[thing] for everything whose queries would be changed
  fn modify (&mut self, accessor: InvalidationAccessor, modification: Modification, event: EventHandle)->DataToUndoModification;
  // audit: if all modifications from a certain event are undone, all query results immediately before and after that event are identical
  fn undo (&mut self, accessor: InvalidationAccessor, modification: DataToUndoModification, event: EventHandle);
}
trait Event: StewardData {
  fn execute (&mut self, accessor: EventAccessor);
  //audit: undoes every action done by execute(), and leaves self in its original state
  fn undo (&mut self, interface: UndoEventInterface);
}
trait Predictor: StewardData {
  fn execute (&mut self, accessor: PredictorAccessor);
}

trait Accessor {
  fn query <Query: StewardData, T: DataTimelineQueriableWith<Query>> (&self, handle: & DataTimelineHandle <T>, query: Query)-> T::QueryResult;
}
trait EventAccessor: Accessor {
  fn modify <Modification: StewardData, T: DataTimelineModifiableWith<Modification>> (&self, handle: & DataTimelineHandle <T>, query: Query)-> T::DataToUndoModification;
  fn event (&self)->& EventHandle;
}
// not called an accessor because it can't query
trait UndoEventInterface {
  // not permitted to query because query results wouldn't necessarily correspond to those observed by the original execution in any way
  fn undo <Modification: StewardData, T: DataTimelineModifiableWith<Modification>> (&self, handle: & DataTimelineHandle <T>, data: T::DataToUndoModification);
  fn event (&self)->& EventHandle;
}
trait PredictorAccessor: Accessor {
  // this one may record dependencies when querying
  // and intentionally doesn't expose the time
  fn predict_at_time (&self, time: ExtendedTime, event: Event);
  fn predict_immediately (&self, event: Event);
}
trait InvalidationAccessor {
  // permitted to get read-only views to all parts of the state, with no tracking of queries
  fn peek <T: DataTimeline> (&self, handle: & DataTimelineHandle <T>)->& T;
  fn invalidate_predictions <T: Predictor> (&self, handle: & PredictorHandle <T>, time_range: TimeRange);
  fn invalidate_event <T: Event> (&self, handle: & EventHandle <T>) ;
}
... EventHandle: Clone {
  fn time (&self)->& ExtendedTime;
}

struct DataTimelineHandle <GlobalLists: GlobalLists, Timeline: DataTimeline> {
  data: DynamicArc <GlobalLists, StewardsTimesDataTimelines, DataTimelineId>,
}
impl<GlobalLists: GlobalLists, Timeline: DataTimeline> DataTimeline for DataTimelineHandle <GlobalLists, Timeline> {
  // forward all??
  fn query <A: Accessor> (&self, query: Self::Query, accessor: &A)->Result <QueryResult<Self>,> {
    self.data.differentiated<Times<A::Steward, Timeline>>().query(query, accessor);
  }
}

trait Mutator : ??? + Rng {
  type Steward: Steward;
  fn create <T: DataTimeline> (&mut self, constants: T::Constants)->DataTimelineHandle <T, Self::Steward>;
  // not needed because they can invoke on the DataTimelineHandle directly, passing in this accessor
  //fn query <T: DataTimeline> (&self, t: DataTimelineHandle<T, Self::Steward>, query: T::Query)->Result <QueryResult<Self>,>{t.data.get (...).downcast_ref().expect().query(), }
  ;
}

trait TimeSteward {
  type Basics: Basics;
  type Mutator: Mutator <Steward = Self>;
  type DataTimelineHandle: DataTimelineHandleData <Steward = Self>;
}

trait TimeSteward {
  fn initialized_with <I: FnOnce (&mut Mutator)->Self::Basics::GlobalTimeline> (time: Self::Basics::Time, initializer: I)->Self;
}

impl Event for Struct {
  ...
  fn call <M: Mutator <...>> (& self, mutator: M) {
    let timeline: DataTimelineHandle <GlobalLists, MyType> = self.timeline;
    let value: &MyType = timeline.query (mutator, MyValue);
    ...
    let new_timeline = mutator.create <MyType>(constants);
  }
}

<commit_msg>more api work<commit_after>/// Data used for a TimeSteward simulation, such as times, entities, and events.
///
/// TimeSteward has strong requirements for serializability. In addition to implementing these traits, a StewardData must have Eq be equivalent to equality of its serialization, and all its behavior must be invariant under cloning and serialize-deserialize cycles.
pub trait StewardData: Any + Send + Sync + Clone + Eq + Serialize + Deserialize + Debug {}

trait TimeStewardModificationReverter {
  fn revert (event: ?????)->invalidated stuff etc., like the return value of the original modify functions;
}

/**

Loosely speaking, these must be retroactive data structures.

Specifically, I'll call them **stack-retroactive data structures**. They are like fully retroactive data structures, except that operations in the past are also permitted to delete arbitrary subsets of the existing operations that are later in time. This leniency is because:
* Data structures can be more efficient if they don't have to support insertion or deletion in the middle, and
* In many cases, the later operations would almost certainly be invalidated anyway if the earlier one was invalidated.

They must obey these conditions:
* The result of a query from a non-snapshot accessor must depend only on the initial snapshot and currently existing operations, and not, for instance, on the order the operations were added. It MAY depend on the order of operations among operations at the exact same ExtendedTime. Query results must also be invariant under taking snapshots at earlier historical times and restoring from them.
* Also, the existing predictors are implicit in the current state. They may not change over serializing and deserializing through a snapshot.
* The results of a query/snapshot from a *snapshot accessor* must depend only on the initial snapshot and operations that existed *at the time the snapshot accessor was created*. (In order to maintain this condition, the structure may have to examine the supplied snapshots structure during insert_operation().) This condition may be violated if forget_snapshot() has been called for that snapshot.
* If a change to the operations would change the result of an earlier query (earlier in program time, >= in historical time), and that earlier query submitted a InvalidationHandle, that update operation must invalidate it by including an equal InvalidationHandle in its return value. (False-positives are permitted, though undesirable). It need only return each InvalidationHandle once. Note that it does NOT have to retain copies of every handle submitted, if it has some way of looking them up, for example by querying other DataTimelines.
* Any method called at a historical time > self.valid_since() must return Ok. self.valid_since() must be TheBeginning when a with_steward() is created, and After (time) when a from_snapshot() is created. It must not increase except from calls to discard_before or insert_operation, and if it implements FullDataTimeline, it must not increase from calls to insert_operation either.

They also *should* obey these conditions:
* whenever the structure stores obsolete information to maintain a snapshot, it should notify the snapshot using ????? so that the snapshot may free up the memory using forget_snapshot() when it is dropped.

*/
struct QueryResult <Timeline: DataTimeline> {
  data: Timeline::QueryResultData;
  valid_until: something < ExtendedTime <Whatever::Steward::Basics>>;
}
struct OperationResult <Timeline: DataTimeline> {
  invalidated_queries: Vec<InvalidationHandle>;
  deleted_future_operations: Vec<(EventHandle, Operation)>; ?????
  created_predictors: Vec<PredictorHandle>;
  deleted_predictors: Vec<PredictorHandle>;
}
struct FromSnapshotResult <Timeline: DataTimeline> {
  created_predictors: Vec<PredictorHandle>;
}
// DataTimeline handles serialize to DataTimelineId
//but the id probably won't be stored in the trait implementor
 // fn id (&self)->DataTimelineId;
trait DataTimeline: Any + UniquelyIdentifiedType {

  type Steward: TimeSteward;
  type Constants: StewardData;

  // All inputs are required to have a standard format, so that the structure can be audited.
  type Query: StewardData;
  type QueryResultData: StewardData;
  type Operation: StewardData;
  type Snapshot: StewardData;

  fn from_constants (steward: StewardHandle <Self::Steward>, constants: Self::Constants)->Self;
  fn from_snapshot (steward: StewardHandle <Self::Steward>, snapshot: &Self::Snapshot)->Self;

  fn constants (&self)->Result <QueryResult<Self>,>;
  fn query <A: Accessor> (&self, query: Self::Query, accessor: &A)->Result <QueryResult<Self>,>;

  // note: I'm not sure this needs an error mode, because having a snapshot prior to the valid_since of a data timeline might be a caller error in a TimeSteward
  fn snapshot (snapshot: &Self::Steward::Snapshot)->Snapshot;

  /// requires a &Steward only so that you can't do it in a predictor or event function.
  //Maybe this should also return a range of times changed so you know what snapshots need to be taken?
  fn insert_operation <Snapshots: SnapshotTree> (&mut self, time: ExtendedTime <Self::Steward::Basics>, operation: Self::Operation, snapshots_to_maintain: & Snapshots, & Steward)->Result <,>;

  fn valid_since (&self, & Steward)->ValidSince <ExtendedTime <Self::Steward::Basics>>;

  fn forget_before (&mut self, time: ExtendedTime <Self::Steward::Basics>, & Steward);
  fn forget_snapshot (&mut self, StewardRc <Steward::Snapshot>);

  // query functions, which take an accessor and possibly a prediction handle, which may be stored in self for future invalidation
  // modify functions, which take a mutator and
  // - possibly return invalidated prediction handles
  // – possibly return spawned predictions, as from creating a new entity
  // - assuming this is for a full TimeSteward, return a StewardRc <TimeStewardModificationReverter> (which, for the simple case, may be a Self). This makes each potential reversion take at least a fat-pointer to store, unless we can make StewardRc be a thin pointer with the vtable at the destination.

  //An operation at time T may create new predictors from T to other times, destroy predictors from T to other times, or invalidate predictions that include After (T).
}

trait SnapshotTree {
  type Steward: TimeSteward;
  fn iterate_snapshots (&self, time_range, since_snapshot_number)->impl Iter<Item = (& Self::Steward::Basics::Time, &StewardRc <Self::Steward::Snapshot>)>;
}

// Model: events interact only through queries at their exact time (which are forbidden to query other timelines or have any side effects) and modifications at their exact time (which are forbidden to return any information). Those modifications, in practice, change the state *going forward from* that time, and may use query_range on other timelines to collect events/predictions that must be invalidated. (Although for instance, modifications made for dependency tracking purposes don't change any results of "real" queries (i.e. those by events and predictors), so they never need to invalidate anything themselves.)
// Predictors cannot modify and can only query??? (The data necessary to invalidate them has to be placed by the events that created them?)
//To audit, we record all of the queries, query results, and modifications. Then after each modification of a DataTimeline, we rerun all queries to that timeline made by still-valid predictions/events. If any query has a different result than before, it's an error. (I guess in order to rerun modifications, we have to feed them the old results of their queries instead of having them do real queries?)
// Also audit: a modification can never change results of queries in the past

// Given a query input, the function (time->query output) must be piecewise constant, changing only at times when modifications have been inserted.
// Event must implement undo. That must call the undo function matching all modifications it made. After an event is undone, there may not remain any modifications at the time of that event. It follows that after doing and then undoing an event, all queries IMMEDIATELY after the event time are restored to their former value. However, queries in the future might not be restored because modifications are permitted to mess up the future(?)

trait DataTimeline: Any {
  // audit: result NEVER changes unless forget_snapshot() is called
  // audit: restoring from version serialized using fresh snapshot doesn't change any query results afterwards
  fn serialize (&self, serializer: &mut something, snapshot: SnapshotHandle);
  fn deserialize (deserializer: something, time: ExtendedTime)->Self;

  // audit: forget functions don't change any query results except those forgotten
  fn forget_before (&mut self, time: ExtendedTime);
  fn forget_snapshot (&mut self, snapshot: SnapshotHandle);
}
trait DataTimelineQueriableWith<Query: StewardData>: DataTimeline {
  type QueryResult: StewardData;

  // audit all functions: must be consistent with each other
  // audit: queries must not have side effects (do a separate action for manual dependency tracking)
  fn query (&self, query: Query, time: ExtendedTime)->QueryResult;
  // permitted to record the dependency
  fn prediction_query (&mut self, query: Query, time: ExtendedTime, predictor: PredictorHandle)->(QueryResult, Option <ExtendedTime>);
  // TODO: is this necessary? Or is it only used in invalidation code, which can peek anyway?
  fn query_range (&self, query: Query, time_range: TimeRange)->impl Iter <Item = (TimeRange, QueryResult)>;

  // audit: NEVER changes unless forget_snapshot() is called
  fn snapshot_query (&self, query: Query, snapshot: SnapshotHandle)->QueryResult;
}
trait DataTimelineModifiableWith<Modification: StewardData>: DataTimeline {
  type DataToUndoModification: StewardData;

  // audit both functions: calls invalidate_[thing] for everything whose queries would be changed
  fn modify (&mut self, accessor: InvalidationAccessor, modification: Modification, event: EventHandle)->DataToUndoModification;
  // audit: if all modifications from a certain event are undone, all query results immediately before and after that event are identical
  fn undo (&mut self, accessor: InvalidationAccessor, modification: DataToUndoModification, event: EventHandle);
}
trait Event: StewardData {
  fn execute (&mut self, accessor: EventAccessor);
  //audit: undoes every action done by execute(), and leaves self in its original state
  fn undo (&mut self, interface: UndoEventAccessor);
}
trait Predictor: StewardData {
  fn execute (&mut self, accessor: PredictorAccessor);
}

// Querying versus peeking:
// Querying accessors are generally for things that can affect the physics. Querying uses an exact interface that can be tracked and audited in various ways to make sure the physics stays consistent.
// Peeking accessors are generally for things that are required to do a specific job and don't have any leeway to change the physics. We allow them full read-only access with no tracking, and merely audit that they did the job they were asked to. Peeking accessors can also be allowed to use the querying interface for convenience (so that they can call generic functions that take a QueryingAccessor), but this currently is only possible for snapshots.
trait QueryingAccessor {
  fn query <Query: StewardData, T: DataTimelineQueriableWith<Query>> (&self, handle: & DataTimelineHandle <T>, query: Query)-> T::QueryResult;
}
trait PeekingAccessor {
  fn peek <T: DataTimeline> (&self, handle: & DataTimelineHandle <T>)->& T;
}
trait MomentaryAccessor {
  fn now(&self) -> Time;
}
trait EventSpecificAccessor {
  fn event (&self)->& EventHandle;
}
trait EventAccessor: QueryingAccessor + EventSpecificAccessor {
  fn modify <Modification: StewardData, T: DataTimelineModifiableWith<Modification>> (&self, handle: & DataTimelineHandle <T>, query: Query)-> T::DataToUndoModification;
}
trait UndoEventAccessor: PeekingAccessor + EventSpecificAccessor {
  // no querying because query results wouldn't necessarily correspond to those observed by the original execution in any way
  fn undo <Modification: StewardData, T: DataTimelineModifiableWith<Modification>> (&self, handle: & DataTimelineHandle <T>, data: T::DataToUndoModification);
}
trait PredictorAccessor: QueryingAccessor {
  // this one may record dependencies when querying
  // and intentionally doesn't expose the time
  fn predict_at_time (&self, time: ExtendedTime, event: Event);
  fn predict_immediately (&self, event: Event);
}
trait InvalidationAccessor: PeekingAccessor {
  // no querying because there may be multiple relevant times
  fn peek <T: DataTimeline> (&self, handle: & DataTimelineHandle <T>)->& T;
  fn invalidate_predictions <T: Predictor> (&self, handle: & PredictorHandle <T>, time_range: TimeRange);
  fn invalidate_event <T: Event> (&self, handle: & EventHandle <T>) ;
}
trait Snapshot: QueryingAccessor + PeekingAccessor + MomentaryAccessor {}
... EventHandle: Clone {
  fn time (&self)->& ExtendedTime;
}

impl <T: EventSpecificAccessor> MomentaryAccessor for T {
  fn now(&self) -> Time {
    self.event.time().base
  }
}

struct DataTimelineHandle <GlobalLists: GlobalLists, Timeline: DataTimeline> {
  data: DynamicArc <GlobalLists, StewardsTimesDataTimelines, DataTimelineId>,
}
impl<GlobalLists: GlobalLists, Timeline: DataTimeline> DataTimeline for DataTimelineHandle <GlobalLists, Timeline> {
  // forward all??
  fn query <A: Accessor> (&self, query: Self::Query, accessor: &A)->Result <QueryResult<Self>,> {
    self.data.differentiated<Times<A::Steward, Timeline>>().query(query, accessor);
  }
}

trait Mutator : ??? + Rng {
  type Steward: Steward;
  fn create <T: DataTimeline> (&mut self, constants: T::Constants)->DataTimelineHandle <T, Self::Steward>;
  // not needed because they can invoke on the DataTimelineHandle directly, passing in this accessor
  //fn query <T: DataTimeline> (&self, t: DataTimelineHandle<T, Self::Steward>, query: T::Query)->Result <QueryResult<Self>,>{t.data.get (...).downcast_ref().expect().query(), }
  ;
}

trait TimeSteward {
  type Basics: Basics;
  type Mutator: Mutator <Steward = Self>;
  type DataTimelineHandle: DataTimelineHandleData <Steward = Self>;
}

trait TimeSteward {
  fn initialized_with <I: FnOnce (&mut Mutator)->Self::Basics::GlobalTimeline> (time: Self::Basics::Time, initializer: I)->Self;
}

impl Event for Struct {
  ...
  fn call <M: Mutator <...>> (& self, mutator: M) {
    let timeline: DataTimelineHandle <GlobalLists, MyType> = self.timeline;
    let value: &MyType = timeline.query (mutator, MyValue);
    ...
    let new_timeline = mutator.create <MyType>(constants);
  }
}

<|endoftext|>


<commit_before>use std::io::Cursor;
use std::io::{Read, Write};

use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use db::row::Row;

// mis info about what's on each page.
const HEADER_SIZE_IN_BYTES : usize = 64;
pub const PAGE_SIZE : usize = 4096;

pub struct Page {
    header: Header,
//    data: [u8; PAGE_SIZE - HEADER_SIZE_IN_BYTES],
    data: Vec<u8>,
    bytes_used: usize, // tracking where we are in the current page

                                      // if we go past the page boundary on a write we fault
}

#[derive(Debug)]
pub enum PageError {
    Full
}

type PageResult<T> = Result<T, PageError>;

struct Header;

impl Header {
    fn as_vec(&self) -> Vec<u8> {
        let result = Vec::with_capacity(HEADER_SIZE_IN_BYTES);
        result
    }
}

// page deals with bytes, and has zero knowledge of a Row
// storage engine needs to serialize
impl Page {
    pub fn new() -> Page {
        let tmp: [u8; PAGE_SIZE - HEADER_SIZE_IN_BYTES];

        Page{header: Header::new(),
             data: Vec::with_capacity(PAGE_SIZE),
             bytes_used: 0,
             }
    }

    // attempt to write to a page
    // can fail if the page is already full
    // if it fails, the storage engine will have to flush this page
    // then allocate a new page
    pub fn write(&mut self, bytes: &[u8]) -> PageResult<()> {
        if bytes.len() > self.space_available() {
            return Err(PageError::Full)
        }
        // we need the length of the row
        let len = bytes.len() as u16;
        self.data.write_u16::<BigEndian>(len);
        self.data.write(bytes);

        self.bytes_used += 2 + len as usize;

        // TODO: update indexes
        Ok(())
    }

    // internal call, try to write instead since it holds a mutable ref
    fn space_available(&self) -> usize {
        PAGE_SIZE - HEADER_SIZE_IN_BYTES - self.bytes_used
    }

    // returns PAGE_SIZE bytes
    pub fn to_bytes(&self) -> Vec<u8> {
        let result = Vec::with_capacity(PAGE_SIZE);
        // get the header
        let header = self.header.as_vec();
        result
    }

}

impl Header {
    fn new() -> Header {
        Header{}
    }
}

#[cfg(test)]
mod tests {
    use super::{Page, HEADER_SIZE_IN_BYTES, PAGE_SIZE};
    #[test]
    fn test_page_insert_ok() {
        let mut p = Page::new();

        assert_eq!(p.space_available(), PAGE_SIZE - HEADER_SIZE_IN_BYTES);
        assert_eq!(p.bytes_used, 0);

        let data: [u8; 16] = [0; 16];
        p.write(&data).expect("Data written");
        // 2 extra bytes from the size
        assert_eq!(p.bytes_used, 18);
    }

    #[test]
    #[should_panic]
    fn test_page_fault() {
        let mut p = Page::new();
        let data: [u8; 5000] = [0; 5000];
        p.write(&data).expect("Failure is expected");
    }
}

<commit_msg>pages can be written to segments.  header still empty<commit_after>use std::io::Cursor;
use std::io::{Read, Write};

use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use db::row::Row;

// mis info about what's on each page.
const HEADER_SIZE_IN_BYTES : usize = 64;
pub const PAGE_SIZE : usize = 4096;

pub struct Page {
    header: Header,
//    data: [u8; PAGE_SIZE - HEADER_SIZE_IN_BYTES],
    data: Vec<u8>,
    bytes_used: usize, // tracking where we are in the current page

                                      // if we go past the page boundary on a write we fault
}

#[derive(Debug)]
pub enum PageError {
    Full
}

type PageResult<T> = Result<T, PageError>;

struct Header;

impl Header {
    fn as_vec(&self) -> Vec<u8> {
        let mut result = Vec::with_capacity(HEADER_SIZE_IN_BYTES);
        result.resize(HEADER_SIZE_IN_BYTES, 0);
        result
    }
}

// page deals with bytes, and has zero knowledge of a Row
// storage engine needs to serialize
impl Page {
    pub fn new() -> Page {
        let tmp: [u8; PAGE_SIZE - HEADER_SIZE_IN_BYTES];

        Page{header: Header::new(),
             data: Vec::with_capacity(PAGE_SIZE),
             bytes_used: 0,
             }
    }

    // attempt to write to a page
    // can fail if the page is already full
    // if it fails, the storage engine will have to flush this page
    // then allocate a new page
    pub fn write(&mut self, bytes: &[u8]) -> PageResult<()> {
        if bytes.len() > self.space_available() {
            return Err(PageError::Full)
        }
        // we need the length of the row
        let len = bytes.len() as u16;
        self.data.write_u16::<BigEndian>(len);
        self.data.write(bytes);

        self.bytes_used += 2 + len as usize;

        // TODO: update indexes
        Ok(())
    }

    // internal call, try to write instead since it holds a mutable ref
    fn space_available(&self) -> usize {
        PAGE_SIZE - HEADER_SIZE_IN_BYTES - self.bytes_used
    }

    // returns PAGE_SIZE bytes
    pub fn to_bytes(&self) -> Vec<u8> {
        let mut result = Vec::with_capacity(PAGE_SIZE);
        // get the header
        let header = self.header.as_vec();
        result.extend(header);
        result.extend(&self.data);
        result.resize(PAGE_SIZE, 0);
        result
    }

}

impl Header {
    fn new() -> Header {
        Header{}
    }
}

#[cfg(test)]
mod tests {
    use super::{Page, HEADER_SIZE_IN_BYTES, PAGE_SIZE};
    #[test]
    fn test_page_insert_ok() {
        let mut p = Page::new();

        assert_eq!(p.space_available(), PAGE_SIZE - HEADER_SIZE_IN_BYTES);
        assert_eq!(p.bytes_used, 0);

        let data: [u8; 16] = [0; 16];
        p.write(&data).expect("Data written");
        // 2 extra bytes from the size
        assert_eq!(p.bytes_used, 18);

        let result = p.to_bytes();
        assert_eq!(result.len(), PAGE_SIZE);
    }

    #[test]
    #[should_panic]
    fn test_page_fault() {
        let mut p = Page::new();
        let data: [u8; 5000] = [0; 5000];
        p.write(&data).expect("Failure is expected");
    }
}

<|endoftext|>


<commit_before>use mio;
use mio::tcp::*;
use mio::{TryRead,TryWrite};
use serde_json as json;

use std::collections::VecDeque;
use std::net::SocketAddr;
use std::fmt;
use std::io::ErrorKind;

use super::{ChainRepl, ChainReplMsg,OpResp, Operation, PeerMsg, ReplicationMessage};
use line_conn::{Encoder, Reader, SexpPeer};

#[derive(Debug)]
pub struct Downstream<T: fmt::Debug> {
    token: mio::Token,
    peer: Option<SocketAddr>,
    // Rather feels like we need to factor this into per-iteration state.
    // ... LAYERS!
    socket: Option<TcpStream>,
    sock_status: mio::EventSet,
    pending: VecDeque<ReplicationMessage>,
    write_buf: Vec<u8>,
    should_disconnect: bool,
    timeout_triggered: bool,
    codec: T,
}

impl Downstream<SexpPeer> {
    pub fn new(target: Option<SocketAddr>, token: mio::Token) -> Self {
       Self::with_codec(target, token, SexpPeer::fresh(token))
    }
}

impl<T: Reader<OpResp> + Encoder<ReplicationMessage> + fmt::Debug> Downstream<T> {
    pub fn with_codec(target: Option<SocketAddr>, token: mio::Token, codec: T) -> Self {
        debug!("Connecting to {:?}", target);
        let mut conn = Downstream {
            token: token,
            peer: target,
            socket: None,
            sock_status: mio::EventSet::none(),
            pending: VecDeque::new(),
            write_buf: Vec::new(),
            should_disconnect: false,
            timeout_triggered: true,
            codec: codec,
        };
        conn
    }

    pub fn reconnect_to(&mut self, target: SocketAddr) {
        if self.peer != Some(target) {
            info!("New downstream: {:?}", target);
            self.peer = Some(target);
            self.should_disconnect = true;
        } else {
            debug!("No change of downstream: {:?}", target);
        }
    }

    pub fn disconnect(&mut self) {
        info!("Disconnect");
        self.peer = None;
        self.should_disconnect = true;
    }

    pub fn send_to_downstream(&mut self, epoch: u64, msg: PeerMsg) {
        debug!("Queuing for downstream (qlen: {}): {:?}: {:?}", self.pending.len()+1, self.peer, msg);
        self.pending.push_back(ReplicationMessage { epoch: epoch, msg: msg });
    }

    pub fn token(&self) -> mio::Token {
        self.token
    }

    pub fn initialize(&self, event_loop: &mut mio::EventLoop<ChainRepl>, token: mio::Token) {
        if let Some(ref sock) = self.socket {
            debug!("Initialize!{:?}", self);
            match event_loop.register_opt(
                    sock,
                    token,
                    mio::EventSet::readable(),
                    mio::PollOpt::edge() | mio::PollOpt::oneshot()) {
                Ok(()) => (),
                Err(e) => {
                    warn!("Registration failed:{}; kind:{:?}", e, e.kind());
                    // self.should_disconnect = true;
                }
            }
        } else {
            warn!("Registering disconnected downstream?!? {:?}", self);
        }
    }

    pub fn handle_event(&mut self, _event_loop: &mut mio::EventLoop<ChainRepl>, events: mio::EventSet) {
        self.sock_status.insert(events);
        trace!("Listener::handle_event: {:?}; this time: {:?}; now: {:?}",
                self.socket.as_ref().map(|s| s.local_addr()), events, self.sock_status);
    }

    pub fn handle_timeout(&mut self) {
        self.timeout_triggered = true
    }

    pub fn process_rules<F: FnMut(ChainReplMsg)>(&mut self, event_loop: &mut mio::EventLoop<ChainRepl>,
            to_parent: &mut F) -> bool {
        trace!("the downstream socket is {:?}", self.sock_status);

        if self.sock_status.is_readable() {
            self.read();
            self.sock_status.remove(mio::EventSet::readable());
        }

        let changed = self.process_buffer(to_parent);

        if self.sock_status.is_writable() {
            self.prep_write_buffer();
            self.write();
            self.sock_status.remove(mio::EventSet::writable());
        }

        if self.sock_status.is_hup() || self.sock_status.is_error() || self.should_disconnect {
            if let Some(sock) = self.socket.take() {
                debug!("Disconnecting socket! {:?}: {:?}", sock, self.sock_status);
                match event_loop.deregister(&sock) {
                    Ok(()) => (),
                    Err(e) => {
                        warn!("Deregister socket failed: {}", e);
                    }
                }
                event_loop.timeout_ms(self.token, 1000).expect("reconnect timeout");
                self.reset();
            }
        }

        if self.socket.is_none() && self.timeout_triggered {
            self.attempt_connect();
            self.initialize(event_loop, self.token);
            self.timeout_triggered = false;
        }

        if !self.is_closed() {
            self.reinitialize(event_loop)
        }
        changed
    }

    fn reset(&mut self) {
        let peer = self.peer.clone();
        let token = self.token.clone();
        let _ = ::std::mem::replace(self, Self::with_codec(peer, token, T::new(token)));
    }

    fn attempt_connect(&mut self) {
        assert!(self.socket.is_none());
        debug!("Connecting: {:?}", self);
        if let &mut Downstream { peer: Some(ref peer), ref mut socket, ref mut sock_status, .. } = self {
            let conn = TcpStream::connect(peer).expect("Connect downstream");
            debug!("New downstream for {:?}! {:?}; {:?}", self.token, self.peer, conn);
            *socket = Some(conn);
            sock_status.remove(mio::EventSet::all());
        } else {
            warn!("Attempting to connect Downstream with no target set");
        }
    }

    fn read(&mut self) {
        let mut abuf = Vec::new();
        if let &mut Downstream { socket: Some(ref mut sock), ref mut codec, token, .. } = self {
            match sock.try_read_buf(&mut abuf) {
                Ok(Some(0)) => {
                    trace!("{:?}: EOF!", token);
                    self.should_disconnect = true
                },
                Ok(Some(n)) => {
                    trace!("{:?}: Read {}bytes", token, n);
                    codec.feed(&abuf);
                },
                Ok(None) => {
                    trace!("{:?}: Noop!", token);
                },
                Err(e) => {
                    error!("got an error trying to read; err={:?}", e);
                    self.should_disconnect = true
                }
            }
        }
    }

    fn prep_write_buffer(&mut self) {
        if let Some(it) = self.pending.pop_front() {
            debug!("Preparing to send downstream (qlen {}): {:?}", self.pending.len(), it);
            let out = self.codec.encode(it);
            self.write_buf.extend(&out);
        }
    }

    fn write(&mut self) {
        if let &mut Downstream { socket: Some(ref mut sock), ref mut write_buf, token, .. } = self {
            match sock.try_write(write_buf) {
                Ok(Some(n)) => {
                    trace!("Downstream: {:?}: Wrote {} of {} in buffer", token, n,
                            write_buf.len());
                    *write_buf = write_buf[n..].to_vec();
                    trace!("Downstream: {:?}: Now {:?}b", sock, write_buf.len());
                },
                Ok(None) => {
                    trace!("Write unready");
                },
                Err(e) => {
                    error!("got an error trying to write; err={:?}", e);
                    self.should_disconnect = true
                }
            }
        }
    }

    fn process_buffer<F: FnMut(ChainReplMsg)>(&mut self, to_parent: &mut F) -> bool {
        let mut changed = false;
       // trace!("{:?}: Read buffer: {:?}", self.socket.peer_addr(), self.read_buf);
        while let Some(cmd) = self.codec.take() {
            debug!("Read message {:?}", cmd);
            to_parent(ChainReplMsg::DownstreamResponse(cmd));

            changed = true;
        }

        changed
    }

    pub fn is_closed(&self) -> bool {
        self.peer.is_none()
    }

    fn reinitialize(&mut self, event_loop: &mut mio::EventLoop<ChainRepl>) {
        if let Some(ref sock) = self.socket {
            let mut flags = mio::EventSet::readable();
            if !(self.write_buf.is_empty() && self.pending.is_empty()) {
                flags.insert(mio::EventSet::writable());
            }
            trace!("Re-register {:?} with {:?}", self, flags);

            match event_loop.reregister(
                    sock,
                    self.token,
                    flags,
                    mio::PollOpt::oneshot()) {
                Ok(()) => (),
                Err(ref e) if e.kind() == ErrorKind::NotFound => {
                    warn!("Re-registration failed:{}; kind:{:?}", e, e.kind());
                    self.should_disconnect = true
                }
                Err(ref e) => {
                    warn!("Re-registration failed:{}; kind:{:?}", e, e.kind());
                    self.should_disconnect = true
                }
            }
        }
    }
}
<commit_msg>Re-use downstream read buffer, and attempt more than one send per iteration.<commit_after>use mio;
use mio::tcp::*;
use mio::{TryRead,TryWrite};
use serde_json as json;

use std::collections::VecDeque;
use std::net::SocketAddr;
use std::fmt;
use std::io::ErrorKind;

use super::{ChainRepl, ChainReplMsg,OpResp, Operation, PeerMsg, ReplicationMessage};
use line_conn::{Encoder, Reader, SexpPeer};

#[derive(Debug)]
pub struct Downstream<T: fmt::Debug> {
    token: mio::Token,
    peer: Option<SocketAddr>,
    // Rather feels like we need to factor this into per-iteration state.
    // ... LAYERS!
    socket: Option<TcpStream>,
    sock_status: mio::EventSet,
    pending: VecDeque<ReplicationMessage>,
    write_buf: Vec<u8>,
    read_buf: Vec<u8>,
    should_disconnect: bool,
    timeout_triggered: bool,
    codec: T,
}

impl Downstream<SexpPeer> {
    pub fn new(target: Option<SocketAddr>, token: mio::Token) -> Self {
       Self::with_codec(target, token, SexpPeer::fresh(token))
    }
}

impl<T: Reader<OpResp> + Encoder<ReplicationMessage> + fmt::Debug> Downstream<T> {
    pub fn with_codec(target: Option<SocketAddr>, token: mio::Token, codec: T) -> Self {
        debug!("Connecting to {:?}", target);
        let mut conn = Downstream {
            token: token,
            peer: target,
            socket: None,
            sock_status: mio::EventSet::none(),
            pending: VecDeque::new(),
            write_buf: Vec::with_capacity(1 << 14),
            read_buf: Vec::with_capacity(1 << 14),
            should_disconnect: false,
            timeout_triggered: true,
            codec: codec,
        };
        conn
    }

    pub fn reconnect_to(&mut self, target: SocketAddr) {
        if self.peer != Some(target) {
            info!("New downstream: {:?}", target);
            self.peer = Some(target);
            self.should_disconnect = true;
        } else {
            debug!("No change of downstream: {:?}", target);
        }
    }

    pub fn disconnect(&mut self) {
        info!("Disconnect");
        self.peer = None;
        self.should_disconnect = true;
    }

    pub fn send_to_downstream(&mut self, epoch: u64, msg: PeerMsg) {
        debug!("Queuing for downstream (qlen: {}): {:?}: {:?}", self.pending.len()+1, self.peer, msg);
        self.pending.push_back(ReplicationMessage { epoch: epoch, msg: msg });
    }

    pub fn token(&self) -> mio::Token {
        self.token
    }

    pub fn initialize(&self, event_loop: &mut mio::EventLoop<ChainRepl>, token: mio::Token) {
        if let Some(ref sock) = self.socket {
            debug!("Initialize!{:?}", self);
            match event_loop.register_opt(
                    sock,
                    token,
                    mio::EventSet::readable(),
                    mio::PollOpt::edge() | mio::PollOpt::oneshot()) {
                Ok(()) => (),
                Err(e) => {
                    warn!("Registration failed:{}; kind:{:?}", e, e.kind());
                    // self.should_disconnect = true;
                }
            }
        } else {
            warn!("Registering disconnected downstream?!? {:?}", self);
        }
    }

    pub fn handle_event(&mut self, _event_loop: &mut mio::EventLoop<ChainRepl>, events: mio::EventSet) {
        self.sock_status.insert(events);
        trace!("Listener::handle_event: {:?}; this time: {:?}; now: {:?}",
                self.socket.as_ref().map(|s| s.local_addr()), events, self.sock_status);
    }

    pub fn handle_timeout(&mut self) {
        self.timeout_triggered = true
    }

    pub fn process_rules<F: FnMut(ChainReplMsg)>(&mut self, event_loop: &mut mio::EventLoop<ChainRepl>,
            to_parent: &mut F) -> bool {
        trace!("the downstream socket is {:?}", self.sock_status);

        if self.sock_status.is_readable() {
            self.read();
            self.sock_status.remove(mio::EventSet::readable());
        }

        let changed = self.process_buffer(to_parent);

        if self.sock_status.is_writable() {
            self.prep_write_buffer();
            self.write();
            self.sock_status.remove(mio::EventSet::writable());
        }

        if self.sock_status.is_hup() || self.sock_status.is_error() || self.should_disconnect {
            if let Some(sock) = self.socket.take() {
                debug!("Disconnecting socket! {:?}: {:?}", sock, self.sock_status);
                match event_loop.deregister(&sock) {
                    Ok(()) => (),
                    Err(e) => {
                        warn!("Deregister socket failed: {}", e);
                    }
                }
                event_loop.timeout_ms(self.token, 1000).expect("reconnect timeout");
                self.reset();
            }
        }

        if self.socket.is_none() && self.timeout_triggered {
            self.attempt_connect();
            self.initialize(event_loop, self.token);
            self.timeout_triggered = false;
        }

        if !self.is_closed() {
            self.reinitialize(event_loop)
        }
        changed
    }

    fn reset(&mut self) {
        let peer = self.peer.clone();
        let token = self.token.clone();
        let _ = ::std::mem::replace(self, Self::with_codec(peer, token, T::new(token)));
    }

    fn attempt_connect(&mut self) {
        assert!(self.socket.is_none());
        debug!("Connecting: {:?}", self);
        if let &mut Downstream { peer: Some(ref peer), ref mut socket, ref mut sock_status, .. } = self {
            let conn = TcpStream::connect(peer).expect("Connect downstream");
            debug!("New downstream for {:?}! {:?}; {:?}", self.token, self.peer, conn);
            *socket = Some(conn);
            sock_status.remove(mio::EventSet::all());
        } else {
            warn!("Attempting to connect Downstream with no target set");
        }
    }

    fn read(&mut self) {
        if let &mut Downstream { socket: Some(ref mut sock), ref mut codec, token, .. } = self {
            match sock.try_read_buf(&mut self.read_buf) {
                Ok(Some(0)) => {
                    trace!("{:?}: EOF!", token);
                    self.should_disconnect = true
                },
                Ok(Some(n)) => {
                    trace!("{:?}: Read {}bytes", token, n);
                    codec.feed(&self.read_buf);
                    self.read_buf.clear();
                },
                Ok(None) => {
                    trace!("{:?}: Noop!", token);
                },
                Err(e) => {
                    error!("got an error trying to read; err={:?}", e);
                    self.should_disconnect = true
                }
            }
        }
    }

    fn prep_write_buffer(&mut self) {
        debug!("Preparing to send downstream (qlen {}; bufsz {})", self.pending.len(), self.write_buf.len());
        while let Some(it) = self.pending.pop_front() {
            let out = self.codec.encode(it);
            self.write_buf.extend(&out);
        }
        debug!("Prepared to send downstream (qlen {}; bufsz {})", self.pending.len(), self.write_buf.len());
    }

    fn write(&mut self) {
        if let &mut Downstream { socket: Some(ref mut sock), ref mut write_buf, token, .. } = self {
            match sock.try_write(write_buf) {
                Ok(Some(n)) => {
                    trace!("Downstream: {:?}: Wrote {} of {} in buffer", token, n,
                            write_buf.len());
                    *write_buf = write_buf[n..].to_vec();
                    trace!("Downstream: {:?}: Now {:?}b", sock, write_buf.len());
                },
                Ok(None) => {
                    trace!("Write unready");
                },
                Err(e) => {
                    error!("got an error trying to write; err={:?}", e);
                    self.should_disconnect = true
                }
            }
        }
    }

    fn process_buffer<F: FnMut(ChainReplMsg)>(&mut self, to_parent: &mut F) -> bool {
        let mut changed = false;
       // trace!("{:?}: Read buffer: {:?}", self.socket.peer_addr(), self.read_buf);
        while let Some(cmd) = self.codec.take() {
            debug!("Read message {:?}", cmd);
            to_parent(ChainReplMsg::DownstreamResponse(cmd));

            changed = true;
        }

        changed
    }

    pub fn is_closed(&self) -> bool {
        self.peer.is_none()
    }

    fn reinitialize(&mut self, event_loop: &mut mio::EventLoop<ChainRepl>) {
        if let Some(ref sock) = self.socket {
            let mut flags = mio::EventSet::readable();
            if !(self.write_buf.is_empty() && self.pending.is_empty()) {
                flags.insert(mio::EventSet::writable());
            }
            trace!("Re-register {:?} with {:?}", self, flags);

            match event_loop.reregister(
                    sock,
                    self.token,
                    flags,
                    mio::PollOpt::oneshot()) {
                Ok(()) => (),
                Err(ref e) if e.kind() == ErrorKind::NotFound => {
                    warn!("Re-registration failed:{}; kind:{:?}", e, e.kind());
                    self.should_disconnect = true
                }
                Err(ref e) => {
                    warn!("Re-registration failed:{}; kind:{:?}", e, e.kind());
                    self.should_disconnect = true
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use engine::EngineData;
use image_convert::image_to_surface;
use scene::SceneName;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::{Rect, Point};
use sdl2::render::{WindowCanvas, Texture, TextureCreator};
use sdl2::surface::Surface;
use sdl2::video::WindowContext;
use sdl2_engine_helpers::scene::{Scene, BoxedScene, SceneChangeEvent};
use std::fs::File;
use std::io::Result;
use std::path::Path;
use map::{Facet, map_id_to_facet, MAP_DETAILS};
use uorustlibs::map::{Block, StaticLocation};
use uorustlibs::art::{ArtReader, Art};
use caches::art_cache::ArtCache;

const STEP_X: u32 = 1;
const STEP_Y: u32 = 1;
const MAX_BLOCKS_WIDTH: u32 = 2;
const MAX_BLOCKS_HEIGHT: u32 = 2;

pub struct WorldScene<'a> {
    art_cache: ArtCache<'a>,
    facet: Facet,
    map_id: u8,
    exiting: bool,
}

impl<'a> WorldScene<'a> {
    pub fn new<'b>(engine_data: &mut EngineData<'b>, texture_creator: &'a TextureCreator<WindowContext>) -> BoxedScene<'a, Event, SceneName, EngineData<'b>> {
        let reader = ArtReader::new(&Path::new("./assets/artidx.mul"), &Path::new("./assets/art.mul")).expect("Could not load art");
        let scene = Box::new(WorldScene {
            exiting: false,
            map_id: 0,
            facet: map_id_to_facet(0),
            art_cache: ArtCache::new(texture_creator),
        });
        scene
    }

    pub fn draw_page(&mut self, renderer: &mut WindowCanvas) {
        self.facet.get_lens(MAX_BLOCKS_WIDTH, MAX_BLOCKS_HEIGHT).map(|lens| {
            for y in 0..lens.height {
                for x in 0..lens.width {
                    let (ref block, ref statics) = lens.blocks[(x + (y * MAX_BLOCKS_WIDTH)) as usize];
                    self.draw_block(renderer, block, statics, &Point::new((22 * 8) + (22 * 8) * x as i32 - (y as i32 * (22 * 8)), (22 * 8) * y as i32 + (x as i32 * (22 * 8))));
                }
            }
        });
    }

    pub fn draw_block(&mut self, renderer: &mut WindowCanvas, block: &Option<Block>, statics: &Option<Vec<StaticLocation>>, target: &Point){
        block.map(|block| {
            for y in 0..8 {
                for x in 0..8 {
                    let cell = block.cells[y * 8 + x];
                    self.art_cache.read_tile(cell.graphic as u32).as_ref().map(|tile| {
                        let query = tile.query();
                        let (offset_x, offset_y) = (target.x(), target.y());
                        renderer.copy(&tile, None, Rect::new((22 * 7) + (22 * x as i32) - (y as i32 * 22) + offset_x, (22 * y as i32) + (x as i32 * 22) + offset_y, query.width, query.height));
                    });
                    /*self.reader.read_tile(cell.graphic as u32).map(|tile| {
                        let image = tile.to_image();
                        let tile_image = image_to_surface(&image);
                        tile_image.blit(None, &mut surface, Some(Rect::new((22 * 7) + (22 * x as i32) - (y as i32 * 22), (22 * y as i32) + (x as i32 * 22), 44, 44))).expect("Failed to blit texture");
                    });*/
                }
            }
        });
    }

}

impl<'a, 'b> Scene<Event, SceneName, EngineData<'b>> for WorldScene<'a> {
    fn render(&mut self, renderer: &mut WindowCanvas, _engine_data: &mut EngineData, _tick: u64) {
        renderer.clear();
        self.draw_page(renderer);
        /*match self.texture {
            Some(ref texture) => {
                renderer.copy(texture, None, None).unwrap();
            },
            None => ()
        };*/
        renderer.present();
    }

    fn handle_event(&mut self, event: &Event, engine_data: &mut EngineData, _tick: u64) {
        match *event {
            Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                self.exiting = true
            },
            Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
                if self.facet.x >= STEP_X as u32 {
                    self.facet.x -= STEP_X as u32;
                }
            },
            Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
                self.facet.x += STEP_X as u32;
            },
            Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
                if self.facet.y >= STEP_Y as u32 {
                    self.facet.y -= STEP_Y as u32;
                }
            },
            Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
                self.facet.y += STEP_Y as u32;
            },
            Event::KeyDown { keycode: Some(Keycode::Tab), .. } => {
                self.map_id = (self.map_id + 1) % MAP_DETAILS.len() as u8;
                self.facet = map_id_to_facet(self.map_id);
            },
             _ => ()
        }
    }

    fn think(&mut self, _engine_data: &mut EngineData, _tick: u64) -> Option<SceneChangeEvent<SceneName>> {
        if self.exiting {
            Some(SceneChangeEvent::PopScene)
        } else {
            None
        }
    }
}
<commit_msg>Horrible screen-filling<commit_after>use engine::EngineData;
use image_convert::image_to_surface;
use scene::SceneName;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::{Color, PixelFormatEnum};
use sdl2::rect::{Rect, Point};
use sdl2::render::{WindowCanvas, Texture, TextureCreator};
use sdl2::surface::Surface;
use sdl2::video::WindowContext;
use sdl2_engine_helpers::scene::{Scene, BoxedScene, SceneChangeEvent};
use sdl2_engine_helpers::transform::TransformContext;
use std::fs::File;
use std::io::Result;
use std::path::Path;
use map::{Facet, map_id_to_facet, MAP_DETAILS};
use uorustlibs::map::{Block, StaticLocation};
use uorustlibs::art::{ArtReader, Art};
use caches::art_cache::ArtCache;

const STEP_X: u32 = 1;
const STEP_Y: u32 = 1;
const MAX_BLOCKS_WIDTH: u32 = 6;
const MAX_BLOCKS_HEIGHT: u32 = 6;

pub struct WorldScene<'a> {
    art_cache: ArtCache<'a>,
    facet: Facet,
    map_id: u8,
    exiting: bool,
}

fn cell_at(x: i32, y: i32) -> TransformContext {
    TransformContext::new()
        .transform(
            (22 * 7) + (22 * x) - (y * 22),
            (22 * y) + (x * 22)
        )
}

// TODO: Make this less nasty
fn block_at(x: i32, y: i32) -> TransformContext {
    TransformContext::new()
        .transform(
            (22 * 8) * x - (y * (22 * 8)) + (22 * 16),
            (22 * 8) * y + (x * (22 * 8)) - (22 * 24)
        )
}

impl<'a> WorldScene<'a> {
    pub fn new<'b>(engine_data: &mut EngineData<'b>, texture_creator: &'a TextureCreator<WindowContext>) -> BoxedScene<'a, Event, SceneName, EngineData<'b>> {
        let reader = ArtReader::new(&Path::new("./assets/artidx.mul"), &Path::new("./assets/art.mul")).expect("Could not load art");
        let scene = Box::new(WorldScene {
            exiting: false,
            map_id: 0,
            facet: map_id_to_facet(0),
            art_cache: ArtCache::new(texture_creator),
        });
        scene
    }

    pub fn draw_page(&mut self, renderer: &mut WindowCanvas) {
        self.facet.get_lens(MAX_BLOCKS_WIDTH, MAX_BLOCKS_HEIGHT).map(|lens| {
            for y in 0..lens.height {
                for x in 0..lens.width {
                    let (ref block, ref statics) = lens.blocks[(x + (y * MAX_BLOCKS_WIDTH)) as usize];
                    let transform = block_at(x as i32, y as i32);
                    self.draw_block(renderer, block, statics, &transform);
                }
            }
        });
    }

    pub fn draw_block(&mut self, renderer: &mut WindowCanvas, block: &Option<Block>, statics: &Option<Vec<StaticLocation>>, context: &TransformContext){
        block.map(|block| {
            for y in 0..8 {
                for x in 0..8 {
                    let cell = block.cells[y * 8 + x];
                    self.art_cache.read_tile(cell.graphic as u32).as_ref().map(|tile| {
                        let query = tile.query();
                        let new_context = cell_at(x as i32, y as i32).merge(context);
                        new_context.copy(renderer, &tile, None, Rect::new(0, 0, query.width, query.height));
                    });
                }
            }
        });
    }

}

impl<'a, 'b> Scene<Event, SceneName, EngineData<'b>> for WorldScene<'a> {
    fn render(&mut self, renderer: &mut WindowCanvas, _engine_data: &mut EngineData, _tick: u64) {
        renderer.clear();
        self.draw_page(renderer);
        renderer.present();
    }

    fn handle_event(&mut self, event: &Event, engine_data: &mut EngineData, _tick: u64) {
        match *event {
            Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                self.exiting = true
            },
            Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
                if self.facet.x >= STEP_X as u32 {
                    self.facet.x -= STEP_X as u32;
                }
            },
            Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
                self.facet.x += STEP_X as u32;
            },
            Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
                if self.facet.y >= STEP_Y as u32 {
                    self.facet.y -= STEP_Y as u32;
                }
            },
            Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
                self.facet.y += STEP_Y as u32;
            },
            Event::KeyDown { keycode: Some(Keycode::Tab), .. } => {
                self.map_id = (self.map_id + 1) % MAP_DETAILS.len() as u8;
                self.facet = map_id_to_facet(self.map_id);
            },
             _ => ()
        }
    }

    fn think(&mut self, _engine_data: &mut EngineData, _tick: u64) -> Option<SceneChangeEvent<SceneName>> {
        if self.exiting {
            Some(SceneChangeEvent::PopScene)
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

extern crate clap;
extern crate rav1e;
extern crate y4m;

mod common;
mod decoder;
use common::*;
use rav1e::*;

use std::io;
use std::io::Write;
use decoder::Decoder;

fn main() {
  let mut cli = parse_cli();
  let mut y4m_dec = y4m::decode(&mut cli.io.input).unwrap();
  let video_info = y4m_dec.get_video_details();
  let mut y4m_enc = match cli.io.rec.as_mut() {
    Some(rec) => Some(
      y4m::encode(
        video_info.width,
        video_info.height,
        y4m::Ratio::new(video_info.time_base.den as usize, video_info.time_base.num as usize)
      ).with_colorspace(y4m_dec.get_colorspace())
        .write_header(rec)
        .unwrap()
    ),
    None => None
  };

  let cfg = Config {
    video_info,
    enc: cli.enc
  };

  let mut ctx = cfg.new_context();

  let stderr = io::stderr();
  let mut err = stderr.lock();

  let _ = writeln!(
    err,
    "{}x{} @ {}/{} fps",
    video_info.width,
    video_info.height,
    video_info.time_base.den,
    video_info.time_base.num
  );

  write_ivf_header(
    &mut cli.io.output,
    video_info.width,
    video_info.height,
    video_info.time_base.den as usize,
    video_info.time_base.num as usize
  );

  let mut progress = ProgressInfo::new(
    Rational { num: video_info.time_base.den, den: video_info.time_base.num },
    if cli.limit == 0 { None } else { Some(cli.limit) },
      cfg.enc.show_psnr
  );

  ctx.set_frames_to_be_coded(cli.limit as u64);

  loop {
    match process_frame(&mut ctx, &mut cli.io.output, &mut y4m_dec, y4m_enc.as_mut()) {
      Ok(frame_info) => {
        for frame in frame_info {
          progress.add_frame(frame);
          let _ = if cli.verbose {
            writeln!(err, "{} - {}", frame, progress)
          } else {
            write!(err, "\r{}                    ", progress)
          };
        }
      },
      Err(_) => break,
    };

    if !ctx.needs_more_frames(progress.frames_encoded() as u64) {
      break;
    }

    cli.io.output.flush().unwrap();
  }

  let _ = write!(err, "\n{}\n", progress.print_stats());
}
<commit_msg>rav1e: Print a more friendly error message when input is not y4m<commit_after>// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

extern crate clap;
extern crate rav1e;
extern crate y4m;

mod common;
mod decoder;
use common::*;
use rav1e::*;

use std::io;
use std::io::Write;
use decoder::Decoder;

fn main() {
  let mut cli = parse_cli();
  let mut y4m_dec = y4m::decode(&mut cli.io.input).expect("input is not a y4m file");
  let video_info = y4m_dec.get_video_details();
  let mut y4m_enc = match cli.io.rec.as_mut() {
    Some(rec) => Some(
      y4m::encode(
        video_info.width,
        video_info.height,
        y4m::Ratio::new(video_info.time_base.den as usize, video_info.time_base.num as usize)
      ).with_colorspace(y4m_dec.get_colorspace())
        .write_header(rec)
        .unwrap()
    ),
    None => None
  };

  let cfg = Config {
    video_info,
    enc: cli.enc
  };

  let mut ctx = cfg.new_context();

  let stderr = io::stderr();
  let mut err = stderr.lock();

  let _ = writeln!(
    err,
    "{}x{} @ {}/{} fps",
    video_info.width,
    video_info.height,
    video_info.time_base.den,
    video_info.time_base.num
  );

  write_ivf_header(
    &mut cli.io.output,
    video_info.width,
    video_info.height,
    video_info.time_base.den as usize,
    video_info.time_base.num as usize
  );

  let mut progress = ProgressInfo::new(
    Rational { num: video_info.time_base.den, den: video_info.time_base.num },
    if cli.limit == 0 { None } else { Some(cli.limit) },
      cfg.enc.show_psnr
  );

  ctx.set_frames_to_be_coded(cli.limit as u64);

  loop {
    match process_frame(&mut ctx, &mut cli.io.output, &mut y4m_dec, y4m_enc.as_mut()) {
      Ok(frame_info) => {
        for frame in frame_info {
          progress.add_frame(frame);
          let _ = if cli.verbose {
            writeln!(err, "{} - {}", frame, progress)
          } else {
            write!(err, "\r{}                    ", progress)
          };
        }
      },
      Err(_) => break,
    };

    if !ctx.needs_more_frames(progress.frames_encoded() as u64) {
      break;
    }

    cli.io.output.flush().unwrap();
  }

  let _ = write!(err, "\n{}\n", progress.print_stats());
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "no_std", no_std)]

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
<commit_msg>testcrate/lib.rs: use #![no_std] unconditionally<commit_after>#![no_std]<|endoftext|>


<commit_before>//
// Copyright (c) 2016, Boris Popov <popov@whitekefir.ru>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

extern crate libc;

use std::cell::Cell;
use self::libc::size_t;
use self::libc::c_int;
use self::libc::c_char;
use std::ptr;
use std::ffi::CString;

//////////////////////////////////////////////////////////////////
pub struct Prober<'a> {
    file:       &'a str,
    raw_prober: Cell<*const i32>
}

impl<'a> Prober<'a> {
    pub fn new(filename: &str) -> Prober {
        Prober{file: filename,
               raw_prober: Cell::new(ptr::null())}
    }

    pub fn probe(&self) -> Result<(), String> {
        let name = CString::new(self.file).unwrap();
        let name_raw = name.into_raw();
        unsafe {
            self.raw_prober.set(blkid_new_probe_from_filename(name_raw));
        }

        if self.raw_prober.get().is_null() {
            return Err("Error in blkid_new_probe_from_filename!".to_string());
        }

        let rr: c_int;
        unsafe {
            rr = blkid_do_probe(self.raw_prober.get());
        }

        if rr < 0 {
            let message = "Error in blkid_do_probe!".to_string();
            return Err(message);
        }
        Ok(())
    }

    pub fn getType(&self) -> Result<String, String> {
        return self.get("TYPE");
    }

    pub fn getLabel(&self) -> Result<String, String> {
        return self.get("LABEL");
    }

    pub fn get(&self, key: &str) -> Result<String, String> {
        let c_key = CString::new(key).unwrap();
        let c_key_raw = c_key.into_raw();
        let mut buff: c_char = 0;
        let mut p_buff: *mut c_char = &mut buff;
        let p_p_buff: *mut *mut c_char = &mut p_buff;
        let i: size_t = 0;
        let p_i: *const size_t  = &i;

        let res: c_int;
        unsafe {
            res = blkid_probe_lookup_value(self.raw_prober.get(),
                                           c_key_raw,
                                           p_p_buff,
                                           p_i);
        }

        if res < 0 {
            let message = "Error in blkid_probe_lookup_value!".to_string();
            return Err(message);
        }

        unsafe {
            let ss = CString::from_raw(p_buff);
            let sss = ss.into_string();
            match sss {
                Ok(r)  => Ok(r),
                _      => Err("Error in CString::into_string!".to_string())
            }
        }
    }
}

impl<'a> Drop for Prober<'a> {
    fn drop(&mut self) {
        let ptr = self.raw_prober.get();
        if ptr.is_null() {
            return;
        }

        unsafe {
            blkid_free_probe(ptr);
        }
    }
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[link(name = "blkid")]
extern {
    fn blkid_new_probe_from_filename(file: *const c_char) -> *const i32;
    fn blkid_do_probe(prober: *const i32) -> c_int;
    fn blkid_probe_lookup_value(prober: *const i32,
                                key: *const c_char,
                                data: *mut *mut c_char,
                                size: *const size_t) -> c_int;
    fn blkid_free_probe(prober: *const i32);
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[test]
fn test_blkid_01() {
    let p = Prober::new("/dev/sda1");
    let p_r = p.probe();
    match p_r {
        Err(r) => {
            println!("{}", r);
            return;
        },
        _       => println!("********* OK ***********")
    }

    let t = p.getType();
    match t {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }

    let l = p.getLabel();
    match l {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }
}
//////////////////////////////////////////////////////////////////
<commit_msg>fix test for blkid<commit_after>//
// Copyright (c) 2016, Boris Popov <popov@whitekefir.ru>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

extern crate libc;

use std::cell::Cell;
use self::libc::size_t;
use self::libc::c_int;
use self::libc::c_char;
use std::ptr;
use std::ffi::CString;

//////////////////////////////////////////////////////////////////
pub struct Prober<'a> {
    file:       &'a str,
    raw_prober: Cell<*const i32>
}

impl<'a> Prober<'a> {
    pub fn new(filename: &str) -> Prober {
        Prober{file: filename,
               raw_prober: Cell::new(ptr::null())}
    }

    pub fn probe(&self) -> Result<(), String> {
        let name = CString::new(self.file).unwrap();
        let name_raw = name.into_raw();
        unsafe {
            self.raw_prober.set(blkid_new_probe_from_filename(name_raw));
        }

        if self.raw_prober.get().is_null() {
            return Err("Error in blkid_new_probe_from_filename!".to_string());
        }

        let rr: c_int;
        unsafe {
            rr = blkid_do_probe(self.raw_prober.get());
        }

        if rr < 0 {
            let message = "Error in blkid_do_probe!".to_string();
            return Err(message);
        }
        Ok(())
    }

    pub fn getType(&self) -> Result<String, String> {
        return self.get("TYPE");
    }

    pub fn getLabel(&self) -> Result<String, String> {
        return self.get("LABEL");
    }

    pub fn get(&self, key: &str) -> Result<String, String> {
        let c_key = CString::new(key).unwrap();
        let c_key_raw = c_key.into_raw();
        let mut buff: c_char = 0;
        let mut p_buff: *mut c_char = &mut buff;
        let p_p_buff: *mut *mut c_char = &mut p_buff;
        let i: size_t = 0;
        let p_i: *const size_t  = &i;

        let res: c_int;
        unsafe {
            res = blkid_probe_lookup_value(self.raw_prober.get(),
                                           c_key_raw,
                                           p_p_buff,
                                           p_i);
        }

        if res < 0 {
            let message = "Error in blkid_probe_lookup_value!".to_string();
            return Err(message);
        }

        unsafe {
            let ss = CString::from_raw(p_buff);
            let sss = ss.into_string();
            match sss {
                Ok(r)  => Ok(r),
                _      => Err("Error in CString::into_string!".to_string())
            }
        }
    }
}

impl<'a> Drop for Prober<'a> {
    fn drop(&mut self) {
        let ptr = self.raw_prober.get();
        if ptr.is_null() {
            return;
        }

        unsafe {
            blkid_free_probe(ptr);
        }
    }
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[link(name = "blkid")]
extern {
    fn blkid_new_probe_from_filename(file: *const c_char) -> *const i32;
    fn blkid_do_probe(prober: *const i32) -> c_int;
    fn blkid_probe_lookup_value(prober: *const i32,
                                key: *const c_char,
                                data: *mut *mut c_char,
                                size: *const size_t) -> c_int;
    fn blkid_free_probe(prober: *const i32);
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[test]
fn test_blkid_01() {
    let p = Prober::new("/dev/sda1");
    let p_r = p.probe();
    match p_r {
        Err(r) => {
            println!("{}", r);
            return;
        },
        _       => println!("********* OK ***********")
    }

    let t = p.getType();
    match t {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }

    let l = p.getLabel();
    match l {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }

    let k = p.get("ARC");
    match k {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }
}
//////////////////////////////////////////////////////////////////
<|endoftext|>