protected override long ReadNext(BitStreamCtxRL ctx) { if (ctx.run_len > 0) { ctx.run_len--; return 1L; } long d = base.ReadNext (ctx); if (d == 1L) { ctx.run_len = (int)(base.ReadNext (ctx) - 1); } return d; }
long BackendAccessRank1(long pos, out long found_pos, BitStreamCtxRL ctx) { if (pos < 0) { found_pos = -1; return 0; } int start_index = -1; if (this.Samples.Count > 0) { start_index = GenericSearch.FindFirst<long> (pos, this.Samples); } // reset run_len ctx.run_len = 0; // int count; if (start_index < 0) { //if (this.Offsets.Count > 0 && this.Offsets[0] == 1) { if (this.Offsets.Count > 0 && this.IsFilled (0)) { found_pos = pos; return pos + 1; } else { ctx.Seek (0); int count = Math.Min (this.B, this.M); return this.SeqAccessRank1 (AccStart, pos, count, out found_pos, ctx); } } int rel_rank = (start_index + 1) * this.B; //if (this.Offsets.Count > start_index + 1 && this.Offsets[start_index + 1] == 1 + this.Offsets[start_index]) { if (this.Offsets.Count > start_index + 1 && this.IsFilled(start_index + 1) ) { found_pos = pos; long diff_rank = pos - this.Samples[start_index]; return rel_rank + diff_rank; } else { ctx.Seek (this.Offsets[start_index]); int count = Math.Min (this.B, this.M - rel_rank); return rel_rank + this.SeqAccessRank1 (this.Samples[start_index], pos, count, out found_pos, ctx); } }
/// <summary> /// build methods /// </summary> public void Build(IEnumerable<long> orderedList, long n, short b, IIEncoder64 coder = null) { this.N = n; this.B = b; this.M = 0; if (coder == null) { coder = new EliasDelta64 (); } this.Coder = coder; long prev = -1; var ctx = new BitStreamCtxRL (); foreach (var current in orderedList) { if (current == 0) { prev = AccStart; } this.M++; long diff = current - prev; //Console.WriteLine ("DIFF {0}, num: {1}, current: {2}", diff, this.M, current); if (diff == 1) { ++ctx.run_len; } else { this.Commit (ctx); // Console.WriteLine ("%%%%%% diff: {0}, prev: {1}, curr: {2}", diff, prev, current); Coder.Encode (this.Stream, diff); } if ((this.M % this.B) == 0) { this.Commit (ctx); this.Samples.Add (current); this.Offsets.Add (this.Stream.CountBits); } if (current >= this.N) { this.N = current + 1; } prev = current; } this.Commit (ctx); /*for (int i = 0; i < this.Samples.Count; i++) { Console.WriteLine ("-- i: {0}, samples: {1}, offset: {2}", i, Samples[i], Offsets[i]); }*/ }
protected override void ResetReader(BitStreamCtxRL ctx) { ctx.run_len = 0; }
public override long Select1(long rank, UnraveledSymbolXLB unraveled_ctx) { Context ctx = unraveled_ctx.ctx as Context; if (ctx == null) { var bctx = new BitStreamCtxRL (); unraveled_ctx.ctx = ctx = new Context (rank, bctx); ctx.prev_res = this.BackendSelect1 ((int)rank, ctx.ctx); } else { int left = (int)(rank - ctx.prev_arg); if (left < 0 || left > this.B * 2) { ctx.prev_res = this.BackendSelect1 ((int)rank, ctx.ctx); } else { for (int i = 0; i < left; i++) { long read = this.ReadNext (ctx.ctx); ctx.prev_res += read; } } } ctx.prev_arg = rank; return ctx.prev_res; }
int SeqAccessRank1(int curr_pos, int pos, int max, out int found_pos, BitStreamCtxRL ctx) { int i = 0; int u = -1; while (i < max && curr_pos < pos) { if (ctx.run_len > 0) { u = ctx.run_len; ctx.run_len = 0; if (curr_pos + u > pos) { u = pos - curr_pos; } curr_pos += u; i += u; } else { u = this.ReadNext (ctx); if (curr_pos + u > pos) { break; } curr_pos += u; i++; } } found_pos = curr_pos; return i; }
long SeqAccessRank1(long acc, long pos, int max, out long found_pos, BitStreamCtxRL ctx) { int i = 0; while (i < max && acc < pos) { long u = this.ReadNext (ctx); if (acc + u > pos) { found_pos = acc; return i; } acc += u; i++; } found_pos = acc; return i; }
long ReadNext(BitStreamCtxRL ctx) { if (ctx.run_len > 0) { ctx.run_len--; return 1; } long d = Coder.Decode (this.Stream, ctx); if (d == 1) { ctx.run_len = ((int)Coder.Decode (this.Stream, ctx)) - 1; } return d; }
long BackendAccessRank1(long pos, out long found_pos, BitStreamCtxRL ctx) { if (pos < 0) { found_pos = -1; return 0; } this.ResetReader (ctx); int start_index = -1; if (this.Samples.Count > 0) { start_index = GenericSearch.FindFirst<long> (pos, this.Samples); } int count; if (start_index < 0) { ctx.Seek (0); count = Math.Min (this.B, this.M); return this.SeqAccessRank1 (AccStart, pos, count, out found_pos, ctx); } ctx.Seek (this.Offsets[start_index]); int rel_rank = (start_index + 1) * this.B; count = Math.Min (this.B, this.M - rel_rank); return rel_rank + this.SeqAccessRank1 (this.Samples[start_index], pos, count, out found_pos, ctx); }
/// <summary> /// Unlocked Select1 useful to some lowlevel operations /// </summary> long BackendSelect1(int rank, BitStreamCtxRL ctx) { if (rank < 1) { return -1; } this.ResetReader(ctx); int start_index = (rank - 1) / this.B; long acc; int left; if (start_index == 0) { acc = AccStart; ctx.Seek (0); left = rank; } else { acc = this.Samples[start_index - 1]; ctx.Seek (this.Offsets[start_index - 1]); left = rank - start_index * this.B; } // int start_acc = acc; for (int i = 0; i < left; i++) { long read = this.ReadNext(ctx); acc += read; } return acc; }
protected virtual void ResetReader(BitStreamCtxRL ctx) { }
protected virtual long ReadNext(BitStreamCtxRL ctx) { return Coder.Decode (this.Stream, ctx); }
/// <summary> /// Returns the difference between Select1(rank) - Select1(rank-1) /// </summary> public long Select1Difference(int rank) { if (rank < 1) { return -1; } if (rank == 1) { return this.Select1 (rank); } var ctx = new BitStreamCtxRL (); this.BackendSelect1 (rank - 1, ctx); return this.ReadNext (ctx); }
long BackendSelect1(int rank, BitStreamCtxRL ctx) { if (rank < 1) { return -1; } // reset run_len ctx.run_len = 0; int start_index = (rank - 1) / this.B; long acc; int left; //Console.WriteLine ("**** BaseSelect1> rank: {0}, start_index: {1}", rank, start_index); if (start_index == 0) { //if (this.Offsets.Count > 0 && this.Offsets [0] == 1) { if (this.Offsets.Count > 0 && this.IsFilled (0)) { //Console.WriteLine ("**** INSIDE FULL> "); ctx.run_len = this.B - rank; return rank - 1; // this.run_len = this.B; } //Console.WriteLine ("**** OUT-SIDE FULL> B: {0}", this.B); acc = AccStart; ctx.Seek (0); left = rank; } else { acc = this.Samples [start_index - 1]; left = rank - start_index * this.B; //if (this.Offsets.Count > start_index && this.Offsets [start_index] == 1 + this.Offsets [start_index - 1]) { if (this.Offsets.Count > start_index && this.IsFilled(start_index)) { ctx.run_len = this.B - left; return acc + left; } ctx.Seek (this.Offsets [start_index - 1]); } // for (int i = 0; i < left; i++) { // int read = this.ReadNext (ctx); // acc += read; // } while (left > 0) { long read; if (ctx.run_len > 0) { read = ctx.run_len; ctx.run_len = 0; left -= (int)read; if (left < 0) { read += left; ctx.run_len += left; left = 0; } } else { read = this.ReadNext (ctx); left--; } acc += read; } return acc; }
public Context(long prev_arg, BitStreamCtxRL ctx) { this.ctx = ctx; this.prev_arg = prev_arg; this.prev_res = long.MinValue; }
void Commit(BitStreamCtxRL ctx) { //Console.WriteLine ("commit run_len: {0}, B: {1}", ctx.run_len, this.B); if (ctx.run_len > 0) { if (ctx.run_len == this.B) { Coder.Encode (this.Stream, 1); } else { Coder.Encode (this.Stream, 1); Coder.Encode (this.Stream, ctx.run_len); } ctx.run_len = 0; } }
int ReadNext(BitStreamCtxRL ctx) { if (ctx.run_len > 0) { ctx.run_len--; return 1; } int d = Coder.Decode (this.Stream, ctx); if (d == 1) { ctx.run_len = Coder.Decode (this.Stream, ctx) - 1; } return d; }
long SeqAccessRank1(long curr_pos, long pos, long max, out long found_pos, BitStreamCtxRL ctx) { long i = 0; long u = -1; while (i < max && curr_pos < pos) { if (ctx.run_len > 0) { u = ctx.run_len; ctx.run_len = 0; if (curr_pos + u > pos) { u = pos - curr_pos; } curr_pos += u; i += u; } else { u = this.ReadNext (ctx); if (curr_pos + u > pos) { break; } curr_pos += u; i++; } } found_pos = curr_pos; return i; }
/// <summary> /// Extract 'count' differences starting from 'start_index', it saves the output in 'output'. /// Returns the previous absolute value to start_index (start_index - 1), i.e. the reference /// </summary> public long ExtractFrom(int start_index, int count, IList<long> output) { long acc; var ctx = new BitStreamCtxRL (); if (start_index == 0) { this.ResetReader (ctx); acc = -1; ctx.Seek (0); } else { acc = this.BackendSelect1 (start_index, ctx); } for (int i = 0; i < count; i++) { long val = this.ReadNext (ctx); if (i < output.Count) { output[i] = val; } else { output.Add (val); } } return acc; }