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; }
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); } }
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; }
/// <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; }