Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F21908378
clientutil.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
clientutil.hpp
View Options
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021-2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include
<libkazv-config.hpp>
#include
<string>
#include
<tuple>
#include
<immer/map.hpp>
#include
<zug/transducer/filter.hpp>
#include
<zug/transducer/eager.hpp>
#include
<lager/deps.hpp>
#include
<boost/container_hash/hash.hpp>
#include
<boost/serialization/string.hpp>
#include
<cursorutil.hpp>
#include
<jobinterface.hpp>
#include
<eventinterface.hpp>
#include
"thread-safety-helper.hpp"
namespace
Kazv
{
struct
ClientModel
;
template
<
class
K
,
class
V
,
class
List
,
class
Func
>
immer
::
map
<
K
,
V
>
merge
(
immer
::
map
<
K
,
V
>
map
,
List
list
,
Func
keyOf
)
{
for
(
auto
v
:
list
)
{
auto
key
=
keyOf
(
v
);
map
=
std
::
move
(
map
).
set
(
key
,
v
);
}
return
map
;
}
inline
std
::
string
keyOfPresence
(
Event
e
)
{
return
e
.
sender
();
}
inline
std
::
string
keyOfAccountData
(
Event
e
)
{
return
e
.
type
();
}
inline
std
::
string
keyOfTimeline
(
Event
e
)
{
return
e
.
id
();
}
inline
std
::
string
keyOfEphemeral
(
Event
e
)
{
return
e
.
type
();
}
struct
KeyOfState
{
std
::
string
type
;
std
::
string
stateKey
;
friend
bool
operator
==
(
const
KeyOfState
&
a
,
const
KeyOfState
&
b
)
=
default
;
};
template
<
class
Archive
>
void
serialize
(
Archive
&
ar
,
KeyOfState
&
m
,
std
::
uint32_t
const
/* version */
)
{
ar
&
m
.
type
&
m
.
stateKey
;
}
inline
KeyOfState
keyOfState
(
Event
e
)
{
return
{
e
.
type
(),
e
.
stateKey
()};
}
template
<
class
Context
>
JobInterface
&
getJobHandler
(
Context
&&
ctx
)
{
return
lager
::
get
<
JobInterface
&>
(
std
::
forward
<
Context
>
(
ctx
));
}
template
<
class
Context
>
EventInterface
&
getEventEmitter
(
Context
&&
ctx
)
{
return
lager
::
get
<
EventInterface
&>
(
std
::
forward
<
Context
>
(
ctx
));
}
/**
* Merge `addon` into the sorted container `base`.
*
* This function will look into every item `x` in `addon`. If `exists(x)`,
* nothing is done. Otherwise, it does a binary search in `base`. If
* there is an item `k` where `keyOf(k) == keyOf(x)`, nothing is done.
* Otherwise, `x` is inserted into `base`, keeping the sort order.
*
* This function invokes at most `O(|addon|*log(|base|))` comparisons; each
* comparison invokes exactly 2 `keyOf`s.
*
* This function invokes at most `|addon|` insertions of `base`.
*
* This function invokes `exists` exactly `|addon|` times.
*
* @param base An immer sequence container of some type T. `base` must be sorted
* in strict ascending order in terms of `keyOf`. I.e., For any two items x, y: `keyOf(x) < keyOf(y)` iff x is before y.
* @param addon A range of the same type T.
* @param exists A function taking T and producing a boolean value.
* @param keyOf A key function for the sorting of `base`. It must be a strong order.
*
*/
template
<
class
ImmerT1
,
class
RangeT2
,
class
Pred
,
class
Func
>
ImmerT1
sortedUniqueMerge
(
ImmerT1
base
,
RangeT2
addon
,
Pred
exists
,
Func
keyOf
)
{
auto
cmp
=
[
=
](
auto
a
,
auto
b
)
{
return
keyOf
(
a
)
<
keyOf
(
b
);
};
for
(
auto
item
:
addon
)
{
if
(
exists
(
item
))
{
continue
;
}
// https://en.cppreference.com/w/cpp/algorithm/upper_bound.html
// *(it-1) <= item < *it
auto
it
=
std
::
upper_bound
(
base
.
begin
(),
base
.
end
(),
item
,
cmp
);
// If `it` is not the first iterator, and `*(it-1) == item`,
// then `item` is already in the list. Otherwise, we are guaranteed
// that `*(it-1)` either does not exist, or `*(it-1) < item`.
// In these cases, `item` is not in the list and we will need
// to add them.
if
(
it
.
index
()
!=
0
&&
keyOf
(
item
)
==
keyOf
(
*
(
it
-
1
)))
{
continue
;
}
auto
index
=
it
.
index
();
base
=
std
::
move
(
base
).
insert
(
index
,
item
);
}
return
base
;
}
std
::
string
increaseTxnId
(
std
::
string
cur
);
std
::
string
getTxnId
(
Event
event
,
ClientModel
&
m
);
}
namespace
std
{
template
<>
struct
hash
<
Kazv
::
KeyOfState
>
{
std
::
size_t
operator
()(
const
Kazv
::
KeyOfState
&
k
)
const
noexcept
{
std
::
size_t
seed
=
0
;
boost
::
hash_combine
(
seed
,
k
.
type
);
boost
::
hash_combine
(
seed
,
k
.
stateKey
);
return
seed
;
}
};
}
#define KAZV_WRAP_ATTR(_type, _d, _attr) \
inline auto _attr() const { \
KAZV_VERIFY_THREAD_ID(); \
return (_d)[&_type::_attr]; \
}
BOOST_CLASS_VERSION
(
Kazv
::
KeyOfState
,
0
)
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Dec 28, 1:43 AM (6 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
761332
Default Alt Text
clientutil.hpp (4 KB)
Attached To
Mode
rL libkazv
Attached
Detach File
Event Timeline
Log In to Comment