Skip to content

Commit d3f27b1

Browse files
committed
continue reworking arcTable by adding ArcTableValues type
1 parent 0651f02 commit d3f27b1

3 files changed

Lines changed: 354 additions & 262 deletions

File tree

src/Core/Helper/Collections.fs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,29 @@ module StringDictionary =
119119
else
120120
dict.Add(key,value)
121121

122+
module IntDictionary =
123+
124+
open System.Collections.Generic
125+
126+
let ofSeq (s : seq<int*'T>) : Dictionary<int,'T> =
127+
s
128+
|> dict
129+
#if !FABLE_COMPILER
130+
|> Dictionary
131+
#else
132+
|> unbox
133+
#endif
134+
135+
let inline tryFind (key : int) (dict : Dictionary<int,'T>) =
136+
let b,v = dict.TryGetValue key
137+
if b then Some v
138+
else None
139+
140+
let inline addOrUpdate (key : int) (value : 'T) (dict : Dictionary<int,'T>) =
141+
if dict.ContainsKey key then
142+
dict.[key] <- value
143+
else
144+
dict.Add(key,value)
122145

123146
module ResizeArray =
124147

@@ -142,6 +165,13 @@ module ResizeArray =
142165
b.Add(f i)
143166
b
144167

168+
let map2 f (a : ResizeArray<_>) (b : ResizeArray<_>) =
169+
let c = ResizeArray<_>()
170+
let n = min a.Count b.Count
171+
for i in 0 .. n - 1 do
172+
c.Add(f a.[i] b.[i])
173+
c
174+
145175
let choose f (a : ResizeArray<_>) =
146176
let b = ResizeArray<_>()
147177
for i in a do

src/Core/Table/ArcTable.fs

Lines changed: 40 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -14,145 +14,58 @@ type TableJoinOptions =
1414
/// Add full columns
1515
| WithValues
1616

17-
18-
[<Erase>]
19-
type ColumnValueRefs =
20-
| Constant of int
21-
| Dense of ResizeArray<int>
22-
23-
member this.RowCount =
24-
match this with
25-
| Constant _ -> None
26-
| Dense values -> Some values.Count
27-
28-
member this.Copy() =
29-
match this with
30-
| Constant valueHash -> Constant valueHash
31-
| Dense values -> Dense(ResizeArray values)
32-
33-
module ArcTableReworkHelpers =
34-
35-
let __DEFAULT_TERM_HASH__ = CompositeCell.emptyTerm.GetHashCode()
36-
let __DEFAULT_DATA_HASH__ = CompositeCell.emptyData.GetHashCode()
37-
let __DEFAULT_FREETEXT_HASH__ = CompositeCell.emptyFreeText.GetHashCode()
38-
let __DEFAULT_UNITIZED_HASH__ = CompositeCell.emptyUnitized.GetHashCode()
39-
40-
let initValueMap() =
41-
let dict = Dictionary<int, CompositeCell>()
42-
let emptyTerm = CompositeCell.emptyTerm
43-
let emptyData = CompositeCell.emptyData
44-
let emptyFreeText = CompositeCell.emptyFreeText
45-
let emptyUnitized = CompositeCell.emptyUnitized
46-
dict.Add(__DEFAULT_TERM_HASH__, emptyTerm)
47-
dict.Add(__DEFAULT_DATA_HASH__, emptyData)
48-
dict.Add(__DEFAULT_FREETEXT_HASH__, emptyFreeText)
49-
dict.Add(__DEFAULT_UNITIZED_HASH__, emptyUnitized)
50-
dict
51-
52-
let createParsedValues(columns: ResizeArray<ResizeArray<CompositeCell>>, valueMap: Dictionary<int, CompositeCell>) =
53-
let parsedColumns =
54-
columns
55-
|> ResizeArray.map(fun column ->
56-
let distinctValues = column |> ResizeArray.distinct
57-
let columnValues = distinctValues |> ResizeArray.map(fun cell ->
58-
let hash = cell.GetHashCode()
59-
if valueMap.ContainsKey hash |> not then
60-
valueMap.Add(hash, cell)
61-
hash
62-
)
63-
match columnValues.Count with
64-
| 1 -> Constant(columnValues.[0])
65-
| _ -> Dense(columnValues |> ResizeArray)
66-
)
67-
|> ResizeArray
68-
let rowCount = parsedColumns |> Seq.choose (fun column -> column.RowCount) |> Seq.max
69-
{| rowCount = rowCount; ParsedColumns = parsedColumns |}
70-
71-
let createCompositeCellValues(valueMap: Dictionary<int, CompositeCell>, internalColumnRefs: ResizeArray<ColumnValueRefs>, rowCount : int) =
72-
internalColumnRefs
73-
|> ResizeArray.map (fun column ->
74-
match column with
75-
| Constant valueHash ->
76-
ResizeArray.create rowCount (valueMap.[valueHash])
77-
| Dense values ->
78-
values |> ResizeArray.map (fun v -> valueMap.[v])
79-
)
80-
81-
let normalizeColumnLengths(rowCount: int, _valueMap: Dictionary<int, CompositeCell>, headers: ResizeArray<CompositeHeader>, _internalColumnRefs: ResizeArray<ColumnValueRefs>) =
82-
for i in 0 .. _internalColumnRefs.Count - 1 do
83-
match _internalColumnRefs.[i] with
84-
| Constant _ -> ()
85-
| Dense values when values.Count = rowCount ->
86-
()
87-
| Dense values when values.Count = 0 ->
88-
let h = headers.[i]
89-
let d = ArcTableAux.Unchecked.getEmptyCellForHeader h None
90-
_internalColumnRefs.[i] <- Constant( d.GetHashCode())
91-
| Dense values when rowCount > values.Count ->
92-
let h = headers.[i]
93-
let last = values |> Seq.last
94-
let d = ArcTableAux.Unchecked.getEmptyCellForHeader h (Some _valueMap.[last])
95-
let diff = rowCount - values.Count
96-
values.AddRange(ResizeArray.create diff (d.GetHashCode()))
97-
| Dense values when rowCount < values.Count ->
98-
let diff = values.Count - rowCount
99-
values.RemoveRange(values.Count - 1, diff)
100-
| anyElse ->
101-
printfn "Unhandled case in ArcTableReworkHelpers.fillMissingCells, please report this as a bug: %A" anyElse
102-
()
103-
104-
10517
[<AttachMembers>]
10618
type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: ResizeArray<ResizeArray<CompositeCell>>) =
10719

108-
10920
let headers = defaultArg headers (ResizeArray<CompositeHeader>())
110-
let columns = defaultArg columns (ResizeArray<ResizeArray<CompositeCell>>([|
111-
for i = 0 to headers.Count - 1 do
112-
ResizeArray.singleton (Unchecked.getEmptyCellForHeader headers.[i] None)
113-
|]))
21+
let columns = defaultArg columns (ResizeArray<ResizeArray<CompositeCell>>())
22+
11423
let valid = SanityChecks.validate headers columns true
115-
let mutable _valueMap = ArcTableReworkHelpers.initValueMap()
24+
let mutable _values = ArcTableValues.fromCellColumns(columns)
11625
let mutable _rowCount = 0
117-
let mutable name = name
118-
let mutable headers: ResizeArray<CompositeHeader> = headers
119-
let mutable _internalColumnRefs: ResizeArray<ColumnValueRefs> =
120-
let d = ArcTableReworkHelpers.createParsedValues(columns, _valueMap)
121-
_rowCount <- d.rowCount
122-
d.ParsedColumns
123-
124-
member this._ValueMap
125-
with internal get() = _valueMap
26+
let mutable _name = name
27+
let mutable _headers: ResizeArray<CompositeHeader> = headers
28+
29+
member this.ValueMap
30+
with internal get() = _values.ValueMap
12631
and internal set(valueMap) =
127-
_valueMap <- valueMap
32+
_values.ValueMap <- valueMap
12833

129-
member this._InternalColumnRefs
130-
with internal get() = _internalColumnRefs
34+
member this.ColumnRefs
35+
with internal get() = _values.Columns
13136
and internal set(internalColumnRefs) =
132-
_internalColumnRefs <- internalColumnRefs
37+
_values.Columns <- internalColumnRefs
13338

13439
member this.Headers
135-
with get() = headers
40+
with get() = _headers
13641
and set(newHeaders) =
13742
// SanityChecks.validate newHeaders values true |> ignore // TODO
138-
headers <- newHeaders
43+
_headers <- newHeaders
13944

14045
member this.Values
141-
with get() = ArcTableReworkHelpers.createCompositeCellValues(_valueMap, _internalColumnRefs, _rowCount)
46+
with get() = _values.ToCellColumns(this.Headers)
14247
// and set(newValues) = // TODO
14348
// SanityChecks.validate headers newValues true |> ignore
14449
// values <- newValues
14550

14651
member this.Name
147-
with get() = name
148-
and internal set (newName) = name <- newName
52+
with get() = _name
53+
and internal set (newName) = _name <- newName
14954

15055
static member create(name, headers, values) = ArcTable(name, headers, values)
15156

15257
/// Create ArcTable with empty 'ValueHeader' and 'Values'
15358
static member init(name: string) =
15459
ArcTable(name, ResizeArray<CompositeHeader>(), ResizeArray())
15560

61+
static member fromArcTableValues (name: string, headers: ResizeArray<CompositeHeader>, values: ArcTableValues) =
62+
let t = ArcTable.init(name)
63+
t.Headers <- headers
64+
t.ValueMap <- values.ValueMap
65+
t.ColumnRefs <- values.Columns
66+
t.RowCount <- values.RowCount
67+
t
68+
15669
/// Will return true or false if table is valid.
15770
///
15871
/// Set `raiseException` = `true` to raise exception.
@@ -168,14 +81,13 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
16881
table.Validate(?raiseException=raiseException)
16982

17083
member this.ColumnCount
171-
with get() = ArcTableAux.getColumnCount this.Headers
84+
with get() = this.Headers.Count
17285

17386
static member columnCount (table:ArcTable) = table.ColumnCount
17487

17588
member this.RowCount
17689
with get() = _rowCount
17790
and set (newRowCount) =
178-
ArcTableReworkHelpers.normalizeColumnLengths(newRowCount, _valueMap, headers, _internalColumnRefs)
17991
_rowCount <- newRowCount
18092

18193
static member getRowCount (table:ArcTable) = table.RowCount
@@ -191,33 +103,20 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
191103

192104
member this.Copy() : ArcTable =
193105
let nextHeaders = this.Headers |> ResizeArray.map (fun h -> h.Copy())
194-
let nextValueMap = Dictionary()
195-
this._ValueMap |> Seq.iter (fun kv ->
196-
nextValueMap.Add(kv.Key, kv.Value.Copy())
197-
)
198-
let nextValues =
199-
this._InternalColumnRefs
200-
|> ResizeArray.map (fun column -> column.Copy())
201-
let t = ArcTable.init(
202-
this.Name
203-
)
204-
t.Headers <- nextHeaders
205-
t._ValueMap <- nextValueMap
206-
t._InternalColumnRefs <- nextValues
207-
t
208-
106+
let nextValues = _values.Copy()
107+
ArcTable.fromArcTableValues(this.Name, nextHeaders, nextValues)
209108

210109
/// Returns a cell at given position if it exists, else returns None.
211-
member this.TryGetCellAt (column: int,row: int) = ArcTableAux.Unchecked.tryGetCellAt (column,row) this.Values
110+
member this.TryGetCellAt (column: int,row: int) = ArcTableAux.Unchecked.tryGetCellAt (column,row) _values
212111

213112
static member tryGetCellAt (column: int,row: int) =
214113
fun (table:ArcTable) ->
215114
table.TryGetCellAt(column, row)
216115

217116
member this.GetCellAt (column: int,row: int) =
218-
try
219-
this.Values.[column,row]
220-
with
117+
failwithf "TODO: Return default value"
118+
match this.TryGetCellAt (column, row) with
119+
| Some c -> c
221120
| _ -> failwithf "Unable to find cell for index: (%i, %i) in table %s" column row this.Name
222121

223122
static member getCellAt (column: int,row: int) =
@@ -254,7 +153,7 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
254153
SanityChecks.validateColumnIndex columnIndex this.ColumnCount false
255154
SanityChecks.validateRowIndex rowIndex this.RowCount false
256155
c.ValidateAgainstHeader(this.Headers.[columnIndex],raiseException = true) |> ignore
257-
Unchecked.setCellAt(columnIndex, rowIndex,c) this.Values
156+
Unchecked.setCellAt(columnIndex, rowIndex,c) _values
258157

259158
/// Update an already existing cell in the table. Fails if cell is outside the columnd AND row bounds of the table
260159
static member updateCellAt(columnIndex: int, rowIndex: int, cell: CompositeCell, ?skipValidation) =
@@ -270,7 +169,7 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
270169
if not(skipValidation) then
271170
SanityChecks.validateColumnIndex columnIndex this.ColumnCount false
272171
c.ValidateAgainstHeader(this.Headers.[columnIndex],raiseException = true) |> ignore
273-
Unchecked.setCellAt(columnIndex, rowIndex,c) this.Values
172+
Unchecked.setCellAt(columnIndex, rowIndex,c) _values
274173

275174
/// Update an already existing cell in the table, or adds a new cell if the row boundary is exceeded. Fails if cell is outside the column bounds of the table
276175
static member setCellAt(columnIndex: int, rowIndex: int, cell: CompositeCell, ?skipValidation) =
@@ -289,7 +188,7 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
289188
let ci,ri = kv.Key
290189
let newCell = f ci ri kv.Value
291190
if not(skipValidation) then newCell.ValidateAgainstHeader(this.Headers[ci],raiseException = true) |> ignore
292-
Unchecked.setCellAt(ci, ri,newCell) this.Values
191+
Unchecked.setCellAt(ci, ri,newCell) _values
293192

294193
/// Update cells in a column by a function.
295194
///
@@ -666,7 +565,7 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
666565
let column = CompositeColumn.create(h,[|row.[columnIndex]|])
667566
SanityChecks.validateColumn column
668567
// Sanity checks - end
669-
Unchecked.addRows index rows this.Headers this.Values
568+
Unchecked.addRows index rows this.Headers _values
670569

671570
static member addRows (rows: CompositeCell [] [], ?index: int) =
672571
fun (table:ArcTable) ->
@@ -679,7 +578,7 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
679578
let row = [|
680579
for columnIndex in 0 .. this.ColumnCount-1 do
681580
let h = this.Headers.[columnIndex]
682-
let tryFirstCell = Unchecked.tryGetCellAt(columnIndex,0) this.Values
581+
let tryFirstCell = Unchecked.tryGetCellAt(columnIndex,0) _values
683582
yield Unchecked.getEmptyCellForHeader h tryFirstCell
684583
|]
685584
let rows = Array.init rowCount (fun _ -> row)
@@ -695,7 +594,7 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
695594
member this.RemoveRow (index:int) =
696595
ArcTableAux.SanityChecks.validateRowIndex index this.RowCount false
697596
// removeCells
698-
Unchecked.removeRowCells_withIndexChange index this.ColumnCount this.RowCount this.Values
597+
Unchecked.removeRowCells_withIndexChange index this.ColumnCount this.RowCount _values
699598

700599
static member removeRow (index:int) =
701600
fun (table:ArcTable) ->
@@ -765,11 +664,11 @@ type ArcTable(name: string, ?headers: ResizeArray<CompositeHeader>, ?columns: Re
765664
columns
766665
|> Array.iter (fun col ->
767666
let prevHeadersCount = this.Headers.Count
768-
Unchecked.addColumn col.Header col.Cells index forceReplace onlyHeaders this.Headers this.Values
667+
Unchecked.addColumn col.Header col.Cells index forceReplace onlyHeaders this.Headers _values
769668
// Check if more headers, otherwise `ArcTableAux.insertColumn` replaced a column and we do not need to increase index.
770669
if this.Headers.Count > prevHeadersCount then index <- index + 1
771670
)
772-
if not(skipFillMissing) then Unchecked.fillMissingCells this.Headers this.Values
671+
if not(skipFillMissing) then Unchecked.fillMissingCells this.Headers _values
773672

774673
static member join(table:ArcTable, ?index: int, ?joinOptions: TableJoinOptions, ?forceReplace: bool) =
775674
fun (this: ArcTable) ->

0 commit comments

Comments
 (0)