Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
80bbf583
Commit
80bbf583
authored
Dec 02, 2007
by
James Hawkins
Committed by
Alexandre Julliard
Dec 03, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Use a hash table for reordering rows in a WHERE query to conserve space.
parent
79e13d17
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
98 additions
and
19 deletions
+98
-19
where.c
dlls/msi/where.c
+98
-19
No files found.
dlls/msi/where.c
View file @
80bbf583
...
...
@@ -35,6 +35,14 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
msidb
);
#define MSI_HASH_TABLE_SIZE 37
typedef
struct
tagMSIHASHENTRY
{
struct
tagMSIHASHENTRY
*
next
;
UINT
value
;
UINT
row
;
}
MSIHASHENTRY
;
/* below is the query interface to a table */
...
...
@@ -44,14 +52,78 @@ typedef struct tagMSIWHEREVIEW
MSIDATABASE
*
db
;
MSIVIEW
*
table
;
UINT
row_count
;
UINT
*
reorder
;
MSIHASHENTRY
*
*
reorder
;
struct
expr
*
cond
;
UINT
rec_index
;
}
MSIWHEREVIEW
;
static
void
free_hash_table
(
MSIHASHENTRY
**
table
)
{
MSIHASHENTRY
*
new
,
*
old
;
int
i
;
if
(
!
table
)
return
;
for
(
i
=
0
;
i
<
MSI_HASH_TABLE_SIZE
;
i
++
)
{
new
=
table
[
i
];
while
(
new
)
{
old
=
new
;
new
=
old
->
next
;
msi_free
(
old
);
}
table
[
i
]
=
NULL
;
}
msi_free
(
table
);
}
static
UINT
find_entry_in_hash
(
MSIHASHENTRY
**
table
,
UINT
row
,
UINT
*
val
)
{
MSIHASHENTRY
*
entry
;
if
(
!
(
entry
=
table
[
row
%
MSI_HASH_TABLE_SIZE
]))
{
ERR
(
"Row not found in hash table!
\n
"
);
return
ERROR_FUNCTION_FAILED
;
}
while
(
entry
&&
entry
->
row
!=
row
)
entry
=
entry
->
next
;
if
(
entry
)
*
val
=
entry
->
value
;
return
ERROR_SUCCESS
;
}
static
UINT
add_entry_to_hash
(
MSIHASHENTRY
**
table
,
UINT
row
,
UINT
val
)
{
MSIHASHENTRY
*
new
=
msi_alloc
(
sizeof
(
MSIHASHENTRY
));
MSIHASHENTRY
*
prev
;
if
(
!
new
)
return
ERROR_OUTOFMEMORY
;
new
->
next
=
NULL
;
new
->
value
=
val
;
new
->
row
=
row
;
prev
=
table
[
row
%
MSI_HASH_TABLE_SIZE
];
if
(
prev
)
new
->
next
=
prev
;
table
[
row
%
MSI_HASH_TABLE_SIZE
]
=
new
;
return
ERROR_SUCCESS
;
}
static
UINT
WHERE_fetch_int
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
UINT
*
val
)
{
MSIWHEREVIEW
*
wv
=
(
MSIWHEREVIEW
*
)
view
;
UINT
r
;
TRACE
(
"%p %d %d %p
\n
"
,
wv
,
row
,
col
,
val
);
...
...
@@ -61,7 +133,9 @@ static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
if
(
row
>
wv
->
row_count
)
return
ERROR_NO_MORE_ITEMS
;
row
=
wv
->
reorder
[
row
];
r
=
find_entry_in_hash
(
wv
->
reorder
,
row
,
&
row
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
return
wv
->
table
->
ops
->
fetch_int
(
wv
->
table
,
row
,
col
,
val
);
}
...
...
@@ -69,6 +143,7 @@ static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *
static
UINT
WHERE_fetch_stream
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
UINT
col
,
IStream
**
stm
)
{
MSIWHEREVIEW
*
wv
=
(
MSIWHEREVIEW
*
)
view
;
UINT
r
;
TRACE
(
"%p %d %d %p
\n
"
,
wv
,
row
,
col
,
stm
);
...
...
@@ -78,7 +153,9 @@ static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
if
(
row
>
wv
->
row_count
)
return
ERROR_NO_MORE_ITEMS
;
row
=
wv
->
reorder
[
row
];
r
=
find_entry_in_hash
(
wv
->
reorder
,
row
,
&
row
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
return
wv
->
table
->
ops
->
fetch_stream
(
wv
->
table
,
row
,
col
,
stm
);
}
...
...
@@ -86,6 +163,7 @@ static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
static
UINT
WHERE_get_row
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
MSIRECORD
**
rec
)
{
MSIWHEREVIEW
*
wv
=
(
MSIWHEREVIEW
*
)
view
;
UINT
r
;
TRACE
(
"%p %d %p
\n
"
,
wv
,
row
,
rec
);
...
...
@@ -95,7 +173,9 @@ static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
if
(
row
>
wv
->
row_count
)
return
ERROR_NO_MORE_ITEMS
;
row
=
wv
->
reorder
[
row
];
r
=
find_entry_in_hash
(
wv
->
reorder
,
row
,
&
row
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
return
wv
->
table
->
ops
->
get_row
(
view
,
row
,
rec
);
}
...
...
@@ -103,6 +183,7 @@ static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
static
UINT
WHERE_set_row
(
struct
tagMSIVIEW
*
view
,
UINT
row
,
MSIRECORD
*
rec
,
UINT
mask
)
{
MSIWHEREVIEW
*
wv
=
(
MSIWHEREVIEW
*
)
view
;
UINT
r
;
TRACE
(
"%p %d %p %08x
\n
"
,
wv
,
row
,
rec
,
mask
);
...
...
@@ -112,7 +193,9 @@ static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI
if
(
row
>
wv
->
row_count
)
return
ERROR_NO_MORE_ITEMS
;
row
=
wv
->
reorder
[
row
];
r
=
find_entry_in_hash
(
wv
->
reorder
,
row
,
&
row
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
return
wv
->
table
->
ops
->
set_row
(
wv
->
table
,
row
,
rec
,
mask
);
}
...
...
@@ -264,7 +347,6 @@ static UINT WHERE_evaluate( MSIWHEREVIEW *wv, UINT row,
}
return
ERROR_SUCCESS
;
}
static
UINT
WHERE_execute
(
struct
tagMSIVIEW
*
view
,
MSIRECORD
*
record
)
...
...
@@ -287,10 +369,10 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
msi_free
(
wv
->
reorder
);
wv
->
reorder
=
msi_alloc
(
count
*
sizeof
(
UINT
)
);
free_hash_table
(
wv
->
reorder
);
wv
->
reorder
=
msi_alloc
_zero
(
MSI_HASH_TABLE_SIZE
*
sizeof
(
MSIHASHENTRY
*
)
);
if
(
!
wv
->
reorder
)
return
ERROR_
FUNCTION_FAILED
;
return
ERROR_
OUTOFMEMORY
;
wv
->
row_count
=
0
;
if
(
wv
->
cond
->
type
==
EXPR_STRCMP
)
...
...
@@ -327,7 +409,7 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
r
=
table
->
ops
->
find_matching_rows
(
table
,
col
,
value
,
&
row
,
&
handle
);
if
(
r
==
ERROR_SUCCESS
)
wv
->
reorder
[
wv
->
row_count
++
]
=
row
;
add_entry_to_hash
(
wv
->
reorder
,
wv
->
row_count
++
,
row
)
;
}
while
(
r
==
ERROR_SUCCESS
);
if
(
r
==
ERROR_NO_MORE_ITEMS
)
...
...
@@ -346,7 +428,7 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
val
)
wv
->
reorder
[
wv
->
row_count
++
]
=
i
;
add_entry_to_hash
(
wv
->
reorder
,
wv
->
row_count
++
,
i
)
;
}
return
ERROR_SUCCESS
;
...
...
@@ -359,10 +441,7 @@ static UINT WHERE_close( struct tagMSIVIEW *view )
TRACE
(
"%p
\n
"
,
wv
);
if
(
!
wv
->
table
)
return
ERROR_FUNCTION_FAILED
;
msi_free
(
wv
->
reorder
);
wv
->
reorder
=
NULL
;
return
ERROR_FUNCTION_FAILED
;
return
wv
->
table
->
ops
->
close
(
wv
->
table
);
}
...
...
@@ -422,7 +501,7 @@ static UINT WHERE_delete( struct tagMSIVIEW *view )
wv
->
table
->
ops
->
delete
(
wv
->
table
);
wv
->
table
=
0
;
msi_free
(
wv
->
reorder
);
free_hash_table
(
wv
->
reorder
);
wv
->
reorder
=
NULL
;
wv
->
row_count
=
0
;
...
...
@@ -444,13 +523,13 @@ static UINT WHERE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return
ERROR_FUNCTION_FAILED
;
r
=
wv
->
table
->
ops
->
find_matching_rows
(
wv
->
table
,
col
,
val
,
row
,
handle
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
if
(
*
row
>
wv
->
row_count
)
return
ERROR_NO_MORE_ITEMS
;
*
row
=
wv
->
reorder
[
*
row
];
return
r
;
return
find_entry_in_hash
(
wv
->
reorder
,
*
row
,
row
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment