--- /dev/null
+
+Ext.data.CSV = Ext.extend(Ext.data.Config, {
+
+ v: undefined, // array of change stamps
+
+ constructor: function(config,callback,scope) {
+ var changed= false;
+ if (config) {
+ config.config_id= 'csv';
+ Ext.data.CSV.superclass.constructor.call(this, config);
+ if (config.v) {
+ this.v= [];
+ this.do_add(config.v);
+ }
+ }
+ if (this.v===undefined) {
+ this.v= [];
+ changed= true;
+ }
+ this.writeAndCallback(changed,callback,scope);
+ },
+
+ add: function(x,callback,scope) {
+ var changed= this.do_add(x);
+ this.writeAndCallback(changed,callback,scope);
+ return this; // JCM should force use of callback?
+ },
+
+ get: function(cs) {
+ return this.v[cs.r];
+ },
+
+ setReplicaNumber: function(replica_number,callback,scope) {
+ this.addReplicaNumbers([replica_number],callback,scope);
+ },
+
+ addReplicaNumbers: function(x,callback,scope) {
+ var t= [];
+ if (x instanceof Array) {
+ t= Ext.data.array.collect(x,function(r){return this.do_add(new Ext.data.CS({r:r}));},this);
+ } else if (x instanceof Ext.data.CSV) {
+ t= Ext.data.array.collect(x.v,function(cs){return this.do_add(new Ext.data.CS({r:cs.r}));},this);
+ }
+ var changed= Ext.data.array.includes(t,true);
+ this.writeAndCallback(changed,callback,scope);
+ },
+
+ do_add: function(x) { // CSV, CS, '1-2-3', [x]
+ var changed= false;
+ if (x instanceof Ext.data.CSV) {
+ var t= Ext.data.array.collect(x.v,this.do_add,this);
+ changed= Ext.data.array.includes(t,true);
+ } else if (x instanceof Ext.data.CS) {
+ var r= x.r;
+ var t= this.v[r];
+ if (!t || x.greaterThan(t)) {
+ this.v[r]= new Ext.data.CS({r:x.r,t:x.t,s:x.s});
+ changed= true;
+ }
+ } else if (typeof x == 'string' || x instanceof String) {
+ changed= this.do_add(new Ext.data.CS(x));
+ } else if (x instanceof Array) {
+ var t= Ext.data.array.collect(x,this.do_add,this);
+ changed= Ext.data.array.includes(t,true);
+ } else {
+ throw "Error - CSV - do_add - Unknown type: "+(typeof x)+": "+x;
+ }
+ return changed;
+ },
+
+ changeReplicaNumber: function(old_replica_number,new_replica_number,callback,scope) {
+ var t= this.v[old_replica_number];
+ var changed= false;
+ if (t) {
+ t.r= new_replica_number;
+ this.v[old_replica_number]= undefined;
+ this.v[new_replica_number]= t;
+ changed= true;
+ }
+ this.writeAndCallback(changed,function(){
+ callback.call(scope,this,changed);
+ },this);
+ },
+
+ isEmpty: function() {
+ return this.v.length<1;
+ },
+
+ maxChangeStamp: function() {
+ if (!this.isEmpty()) {
+ var r= new Ext.data.CS();
+ this.v.forEach(function(cs){
+ var t= new Ext.data.CS({t:cs.t,s:cs.s});
+ r= (t.greaterThan(r) ? cs : r);
+ },this);
+ return r;
+ }
+ },
+
+ dominates: function(x) {
+ return Ext.data.array.any(this.compare(x),function(i){ return i>0; });
+ },
+
+ equals: function(x) {
+ return Ext.data.array.all(this.compare(x),function(i){ return i===0; });
+ },
+
+ compare: function(x) {
+ var i, cs, r;
+ if (x instanceof Ext.data.CS) {
+ cs= this.get(x);
+ return [cs ? cs.compare(x) : -1];
+ } else if (x instanceof Ext.data.CSV) {
+ r= [];
+ for(i in this.v) {
+ cs= this.v[i];
+ if (cs instanceof Ext.data.CS) {
+ var cs2= x.get(cs);
+ r.push(cs2 ? cs.compare(cs2) : 1);
+ }
+ }
+ return r;
+ } else {
+ throw "Error - CSV - compare - Unknown type: "+(typeof x)+": "+x;
+ }
+ return [-1];
+ },
+
+ forEach: function(fn,scope) {
+ this.v.forEach(fn,scope||this);
+ },
+
+ encode: function() { // for the wire
+ return Ext.data.array.collect(this.v,function(){
+ // JCM can we safely ignore replicas with CS of 0... except for the highest known replica number...
+ return this.to_s();
+ });
+ },
+
+ decode: function(x) { // from the wire
+ this.do_add(x);
+ return this;
+ },
+
+ to_s: function(indent) {
+ var r= "CSV: ";
+ this.v.forEach(function(cs){
+ r+= cs.to_s()+", ";
+ },this);
+ return r;
+ },
+
+ as_data: function() { // for the disk
+ var data= {
+ v: Ext.data.array.collect(this.v,function(){return this.to_s();})
+ };
+ data[Ext.data.SyncModel.MODEL]= 'Ext.data.CSV';
+ return Ext.data.CSV.superclass.as_data.call(this, data);
+ }
+
+});
\ No newline at end of file